เสียงสระจากสระ


22

คำอธิบายงาน

บางครั้งคุณต้องพอดีกับสิ่งที่คุณเขียนในพื้นที่เล็ก ๆ มันอาจจะเป็นการดึงดูดให้ทิ้งสระและ wrt lk ths - และความล้มเหลวนั้นใครต้องการช่องว่างจริงๆ? Thssprfctlrdbl!

เขียนฟังก์ชั่นหรือโปรแกรมที่เอาตัวพิมพ์เล็กสระaeiouและช่องว่างแล้วและจากนั้นใด ๆตัวละครจากสายป้อน นอกจากนี้ทุกครั้งที่คุณลบตัวอักษรมันจะต้องเป็นตัวละครที่เหมาะสมที่สุดที่จะถูกลบ มันจะต้องทำซ้ำขั้นตอนนี้จนกว่าสตริงคือไม่เกินระยะเวลาในการป้อนข้อมูลบางส่วนที่ได้รับ

†“ นี่อ่านได้อย่างสมบูรณ์แบบ!” แต่ถ้าคุณอ่านเชิงอรรถนี่อาจจะไม่ใช่ ... จริง ๆ :)

ตัวอย่าง

ที่นี่คุณสามารถเห็นกระบวนการนี้ใช้กับขนาดอินพุตที่เล็กลงอย่างต่อเนื่อง:

23: Hello, Code Golf World!
22: Hello, Code Golf Wrld!
21: Hello, Code Glf Wrld!
20: Hello, Cod Glf Wrld!
19: Hello, Cd Glf Wrld!
18: Hell, Cd Glf Wrld!
17: Hll, Cd Glf Wrld!
16: Hll, Cd GlfWrld!
15: Hll, CdGlfWrld!
14: Hll,CdGlfWrld!
13: Hll,CdGlfWrld
12: Hll,CdGlfWrl
11: Hll,CdGlfWr
(etc.)

หลังจากบีบสตริงลงเหลือ 17 ตัวอักษรเราจะใช้เสียงสระเพื่อเอาออกดังนั้นตัวละครตัวถัดไปที่เราลบคือช่องว่างด้านขวาสุด เมื่อเรากดอักขระ 14 ตัวเราได้ลบสระและช่องว่างทั้งหมดออกไปดังนั้นเราจึงเริ่มเคี้ยวสตริงจากขวาไปซ้าย

นี่คือรหัส Python ของpseudocodeที่แก้ปัญหานี้:

def crunch_string(string, to_length):
    while len(string) > to_length:
        # Store the best candidate index for deletion here.
        best = None

        # First, find the rightmost vowel's index.
        for i in range(len(string)):
            if string[i] in 'aeiou':
                best = i

        # If there were no vowels, find the rightmost space's index.
        if best is None:
            for i in range(len(string)):
                if string[i] == ' ':
                    best = i

        # If there were no spaces either, use the final index.
        if best is None:
            best = len(string) - 1

        # Remove the selected character from the string.
        string = string[:best] + string[best + 1:]

    # Return the string once `len(string) <= to_length`.
    return string

กฎระเบียบ

  • นี่คือดังนั้นโค้ดที่สั้นที่สุดในหน่วยไบต์ชนะ

  • สตริงอินพุตจะประกอบด้วยอักขระ ASCII ที่พิมพ์ได้จากช่องว่าง ( ทศนิยม 32) จนถึงและรวมตัวหนอน ( ~ทศนิยม 126) จะไม่มีสระตัวใหญ่AEIOUในสตริง โดยเฉพาะอย่างยิ่งจะไม่มี Unicode แท็บหรือการขึ้นบรรทัดใหม่ที่เกี่ยวข้อง

  • โทรสายป้อนsและการป้อนข้อมูลความยาวเป้าหมายที แล้ว 0 <T ≤ยาว ( s ) ≤ 10000 มีการประกัน (โดยเฉพาะอย่างยิ่งสายป้อนจะไม่เป็นที่ว่างเปล่า. ถ้าT = ความยาว ( s ), คุณก็ควรจะกลับสตริงแปร.)

กรณีทดสอบ

Input:  50, Duis commodo scelerisque ex, ac consectetur metus rhoncus.
Output: Duis commodo scelerisque ex, ac cnscttr mts rhncs.

Input:  20, Maecenas tincidunt dictum nunc id facilisis.
Output: Mcnstncdntdctmnncdfc

Input:  150, golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf
Output: glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glf glfglfglfglfglfglfglfglfglfglf

5
เป็นyสระเสียง?
edc65

1
ไม่อยากจะเชื่อว่าฉันลืมอธิบาย! ไม่aeiouเป็นเสียงสระและAEIOUจะไม่เกิดขึ้นเพื่อความเรียบง่าย (สิ่งที่เป็นตัวพิมพ์ใหญ่ / ตัวพิมพ์เล็กทั้งหมดไม่ใช่สิ่งที่ฉันต้องการมุ่งเน้น) ฉันเพิ่มความกระจ่าง
ลินน์

1
ความท้าทายที่ดีมาก!
Luis Mendo

@ edc65 อย่าลืมw(ตัวอย่างเช่นในการร่วมคำW , wเป็นเสียงสระ!) ซึ่งแน่นอนว่าตัดสินสำหรับการนี้ แต่ที่มันไม่ได้ระบุว่าชุดของสระคือaeiouบางครั้งคุณควรจะรวมถึงและy w: -O
corsiKa

ไม่เกี่ยวข้องกับการเล่นกอล์ฟ แต่ให้พิจารณาfor index, char in enumerate(string)แทนที่จะrange(len(str))สร้าง
Jeremy Weirich

คำตอบ:


6

MATL , 20 ไบต์

t11Y2mEG32=+K#Si:)S)

ลองออนไลน์!

t       % implicitly input string. Duplicate
11Y2    % predefined literal 'aeiou'
m       % ismember. Gives true for input characters that are vowels
E       % multiply by 2
G       % push input string again
32      % ASCII for space
=       % gives true for input characters that are spaces
+       % add: gives 2 for vowels, 1 for space, 0 for non-vowels-and-non space
K#S     % sort and push only the indices of the sorting. Sorting is stable, so first 
        % will be non-vowels-and-non space characters in their original order, then
        % spaces in their original order, then vowels in their original order
i       % input number n of characters that should be kept
:       % range [1,2,...,n]
)       % index with that: keep first n indices of the sorting
S       % sort those indices to restore their original order
)       % index into input string to keep only those characters. Implicitly display

11

Perl, 48 45 43 ไบต์

รวมถึง +4 สำหรับ-Xlpi(-X สามารถออกไปได้ แต่ทิ้งคำเตือนที่น่าเกลียดไว้ที่ STDERR)

รันด้วยหมายเลขหลังจาก-iตัวเลือกและอินพุตบน STDIN (รองรับหลายบรรทัดด้วย) เช่นperl -Xlpi50 crunch.pl <<< "Duis commodo scelerisque ex, ac consectetur metus rhoncus."

crunch.pl:

s/.*\K[aeiou]|.*\K |.$// while pos=-$^I

คุณไม่ต้องการช่องว่างระหว่าง/$+/และwhile
hmatt1

ฉันคิดว่าคุณโกนไบต์ด้วยการใช้ ^ I (อักขระแท็บ) แทน "^ I" (ยังไม่ทดลอง)
msh210

@chilemagic: ปล่อยช่องว่างระหว่าง / $ + / และในขณะที่ใช้งานได้เฉพาะกับ perls ที่เก่ากว่าเท่านั้น perls ล่าสุดเปลี่ยน parser เพื่อให้เปิดความสามารถในการเพิ่มตัวปรับแต่ง regex ใหม่ (เช่นตัวดัดแปลง aw)
Ton Hospel

@ msh210: ใช้งานได้กับตัวแปรเวทย์มนตร์บางอย่าง แต่ไม่ใช่สำหรับตัวแปรที่ขึ้นอยู่กับช่องว่าง
Ton Hospel

6

JavaScript (ES6), 66 61 ไบต์

บันทึก 5 ไบต์ด้วย @Neil

f=(s,n)=>s[n]?f(s.replace(/(.*)[aeiou]|(.*) |.$/,"$1$2"),n):s

ฉันไม่คิดว่า regex สามารถเล่นกอล์ฟได้อีก น่าแปลกที่สั้นที่สุดที่ฉันสามารถหาได้เพื่อลบแบบหน้าต่อหลังนั้นยาวกว่าไบต์:

f=(s,n)=>s[n]?f(s.replace(/(.*?)[aeiou]|(.*?) |./,"$1$2"),n):s

ความพยายามที่น่าสนใจยิ่งขึ้น (ES7), 134 ไบต์

(s,n,i=0)=>[for(c of s)[/[aeiou]/.test(c)*2+(c<'!'),i++,c]].sort(([x],[y])=>x-y).slice(0,n).sort(([,x],[,y])=>x-y).map(x=>x[2]).join``

วิธีนี้ใช้วิธีการคล้ายกับคำตอบ MATL


1
ฉันไม่สนใจว่ามันจะไม่สามารถเล่นกอล์ฟได้หรือไม่นั่นเป็น regex ที่สวยงาม
Neil

แม้ว่าฉันเพิ่งสังเกตเห็นว่าคุณสามารถใช้|.$/,"$1$2"เพื่อบันทึก 5 ไบต์
Neil

@ Neil ขอบคุณสำหรับเคล็ดลับ!
ETHproductions

2

sh + gnu sed, 78 61

ใส่สตริงให้STDINกับความยาวเป็นอาร์กิวเมนต์แรก

rev|sed -r ":                       # reverse + invoke sed + jump label ":"
/..{$1}/!q                          # if the length is not greater $1, quit
p                                   # print
s/[aeiou]//                         # delete the first vowel
t                                   # if successful, start over at ":"
s/ //                               # delete the first space
t                                   # if successful, start over at ":"
s/.//                               # delete the first character
t"|rev                              # if successful, start over at ":" + reverse

2

Lua ขนาด 120 ไบต์

s=arg[2]:reverse()a=s:len()-arg[1]s,n=s:gsub('[aeiou]','',a)s,m=s:gsub(' ','',a-n)print(s:gsub('.','',a-n-m):reverse())

จะเข้าเป็นอาร์กิวเมนต์บรรทัดคำสั่งในรูปแบบที่มีเอาท์พุทlua crunch.lua 10 "This is a string"Ths sstrng

คำอธิบาย:

-- Set 's' to the reverse of the string
s=arg[2]:reverse()
-- Set 'a' to the number of characters to be removed
a=s:len()-arg[1]
-- Remove 'a' vowels, set 'b' to the number of substitutions
s,b=s:gsub('[aeiou]','',a)
-- Remove 'a-b' spaces, set 'c' to the number of substitutions
s,c=s:gsub(' ','',a-b)
-- Remove 'a-b-c' characters, and print the now un-reversed string
print(s:gsub('.','',a-b-c):reverse())

1

Perl, 68

การลบออกจากด้านขวาจะเป็นการเพิ่มอักขระจำนวนหนึ่งซึ่งอาจเป็นวิธีที่ดีกว่าในการทำเช่นนี้

$_=reverse;while(length>$^I){s/[aeiou]//||s/ //||s/.//}$_=reverse

ใช้-iเพื่อป้อนหมายเลข มันเป็น 65 ตัวอักษรบวก 3 สำหรับi, pและlในบรรทัดคำสั่ง

ทำงานด้วย:

echo 'Hello, Code Golf World!' | perl -i13 -ple'$_=reverse;while(length>$^I){s/[aeiou]//||s/ //||s/.//}$_=reverse'

คุณสามารถใช้y///cแทนlengthและคุณสามารถย้าย while loop ไปยังจุดสิ้นสุด:s///||s///||s///while$^I<y///c
andlrc

1

Java 8, 303 ไบต์

(s,j)->{String t="";for(int i=s.length()-1;i>=0;t+=s.charAt(i--));while(t.length()>j&&t.matches(".*[aeiou].*"))t=t.replaceFirst("[aeiou]","");while(t.length()>j&&t.contains(" "))t=t.replaceFirst("\\s","");s="";for(int i=t.length()-1;i>=0;s+=t.charAt(i--));return s.substring(0,Math.min(t.length(),j));};

นี่คือวิธียาวเกินไป ไม่ลองย่อให้สั้นลง มันจะสั้นกว่านี้มากหาก java มีวิธีการย้อนกลับสตริงและการเปลี่ยนย้อนหลัง

ทดสอบกับสิ่งต่อไปนี้:

public class StringCruncher {
    public static void main(String[] args) {
        Tester test = (s,j)->{String t="";for(int i=s.length()-1;i>=0;t+=s.charAt(i--));while(t.length()>j&&t.matches(".*[aeiou].*"))t=t.replaceFirst("[aeiou]","");while(t.length()>j&&t.contains(" "))t=t.replaceFirst("\\s","");s="";for(int i=t.length()-1;i>=0;s+=t.charAt(i--));return s.substring(0,Math.min(t.length(),j));};
        System.out.println(test.crunch("golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf", 150));
    }
}
interface Tester {
    String crunch(String s, int j);
}

1
คนส่วนใหญ่ที่ครอบงำในเมตาบอกว่าคุณสามารถบันทึกไบต์ด้วย
แกงกะหรี่

@ ดูเหมือนว่าการแกงไม่ทำงานในกรณีนี้ ( s->j->{...}) ฉันคิดว่า Java ไม่สนับสนุนอย่างดีหรือฉันตั้งค่าผิด
GamrCorps

ภาษาที่คอมไพล์อาจมีปัญหาในการแก้ตัวเนื่องจากฟังก์ชั่นเฟิร์สคลาส
CalculatorFeline

@GamrCorps ฉันจะตรวจสอบและดูว่าผมสามารถทำให้มันทำงานเมื่อฉันได้รับบ้าน
Cyoce

1

C #, 180 ไบต์

string c(int l,string s){while(s.Length>l){int i=0;Func<string,bool>f=t=>(i=s.LastIndexOfAny(t.ToCharArray()))!=-1;if(!(f("aeiou")||f(" ")))i=s.Length-1;s=s.Remove(i,1);}return s;}

Tester:

using System;
class Crunch
{
    static int Main()
    {
        var x = new Crunch();
        Console.WriteLine(x.c(50, "Duis commodo scelerisque ex, ac consectetur metus rhoncus."));
        Console.WriteLine(x.c(20, "Maecenas tincidunt dictum nunc id facilisis."));
        Console.WriteLine(x.c(150, "golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf golf"));
        Console.Read();
        return 0;
    }
    string c(int l,string s){while(s.Length>l){int i=0;Func<string,bool>f=t=>(i=s.LastIndexOfAny(t.ToCharArray()))!=-1;if(!(f("aeiou")||f(" ")))i=s.Length-1;s=s.Remove(i,1);}return s;}

    static string crunch(int len, string str)
    {
        Console.WriteLine($"{str.Length}: {str}");
        while (str.Length > len) {
            int idx=0;
            Func<string,bool> f = s => (idx = str.LastIndexOfAny(s.ToCharArray()))!= -1;
            if (!(f("aeiou") || f(" "))) idx = str.Length-1;
            str = str.Remove(idx,1);
            Console.WriteLine($"{str.Length}: {str}");
        }
        return str;
    }
}

1

สกาลา, 160 ไบต์

type S=String;def f(s:S,l:Int)={def r(s:S,p:S):S=if(s.size>l){val j=s.replaceFirst("(?s)(.*)"+p,"$1");if(j==s)s else r(j,p)}else s;r(r(r(s,"[aeiou]")," "),".")}

Tester:

val t="Hello, Code Golf World!"
println((t.size to 11 by -1).map(f(t,_)).mkString("\n"))

1

Dyalog APL, 77 45 42 ไบต์

t[⌽i~⌽⎕↓⌽∪∊(t∊'aeiou')(' '=t)1/¨⊂i←⍳⍴t←⌽⍞]

t[... ]ตัวอักษรของtพร้อมดัชนี ...
t←⌽⍞ tรับการป้อนข้อความแบบย้อนกลับ
i←⍳⍴t ฉันได้รับดัชนีความยาวของt
/¨⊂iหลายรายการ (3) บูลีนการเลือกองค์ประกอบของi :
1. (t∊'aeiou')บูลีนที่สระ
2. (' '=t)บูลีนที่พื้นที่
3. เอกลักษณ์1ทั้งหมด ∪∊ของเกณฑ์ ( แบน) 3 ตัวเลือก
⌽⎕↓⌽วางอักขระที่ประเมินค่าล่าสุด (เช่น(-⎕)↓)
⌽i~ย้อนกลับดัชนีที่เหลือหลังจากลบบางส่วน


คำตอบเดิม:

⎕{⍺≥≢⍵:⌽⍵⋄∨/⍵∊⍨v←'aeiou':⍺∇⍵/⍨~<\(⍳⍴⍵)∊⍵⍳v⋄' '∊⍵:⍺∇⍵/⍨~<\(⍳⍴⍵)=⍵⍳' '⋄⍺∇1↓⍵}⌽⍞

เอ๊ะใช่แล้วมันอ่านยากหน่อย โดยทั่วไปการแปลโดยตรงของ OP เป็น APL:

  1. ย้อนกลับอินพุต
  2. หากความยาวที่ต้องการยาวกว่าหรือเท่ากับจำนวนของสตริงอินพุต (กลับด้าน) จากนั้นส่งคืนอาร์กิวเมนต์ย้อนกลับ (กลับด้าน)
  3. อื่นถ้าอาร์กิวเมนต์มีสระใด ๆ ให้ลบหนึ่ง (เช่นล่าสุด) หนึ่งและเรียกซ้ำในสิ่งที่เหลืออยู่
  4. อื่นถ้าอาร์กิวเมนต์มีช่องว่างให้ลบหนึ่ง (เช่นล่าสุด) หนึ่งและเรียกซ้ำในสิ่งที่ยังคงอยู่
  5. อื่นลบอักขระ (เช่นสุดท้าย) ตัวแรกและโทรซ้ำในสิ่งที่เหลืออยู่

0

Mathematica, 201 ไบต์

f@x_:=StringReplaceList[x,"a"|"e"|"i"|"o"|"u"->""];g@x_:=StringReplaceList[x," "->""];x_~l~y_:=NestWhile[If[f@#!={},Last@f@#,If[g@#!={},Last@g@#,Last@StringReplaceList[#,_->""]]]&,x,StringLength@#!=y&]

ต้องมีวิธีที่ดีกว่านี้ ..


0

R, 169 143 ไบต์

function(x,y){d=utf8ToInt(x);o=c(rev(which(d%in%utf8ToInt('aeiou'))),rev(which(d==32)));intToUtf8(d[sort(tail(c(o,setdiff(nchar(x):1,o)),y))])}

* แก้ไขบันทึกแล้ว 36 ไบต์ผ่านการเขียนซ้ำด้วย utf8ToInt -> intToUtf8แปลงไม่ได้strstplitและpaste0(...,collapse)

ungolfed พร้อมคำอธิบาย

function(x,y){d=utf8ToInt(x);         # convert string (x) to integer
o=c(
 rev(which(d%in%utf8ToInt('aeiou'))), # index of vowels (reversed)
 rev(which(d==32)));                  # index of spaces
 intToUtf8(d[                         # convert subset back to character
   sort(tail(                         # return the first y index of 
                                      # "left over" characters
   c(o,setdiff(nchar(x):1,o))         # combine vowels, spaces and 
                                      # other indices in appropriate order
  ,y))])}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.