Хрустіть голосні з рядка


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-коду, який вирішує цю проблему:

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 , а довжина введення - t . Тоді 0 <t ≤ довжина ( и ) ≤ 10000 гарантована. (Зокрема, рядок вводу ніколи не буде порожньою. Якщо t = length ( 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
Дуже приємний виклик!
Луїс Мендо

@ Edc65 Не забудьте w(наприклад, в слові зі ш , wгласний!) Звичайно, це залагоджено для цього, але там , де це не вказано , що безліч голосних aeiou, ви повинні іноді включати yі w. : -O
corsiKa

for index, char in enumerate(string)range(len(str))
Немає стосунку

Відповіді:


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 (символ вкладки) замість «^ Я». (Неперевірено.)
msh210

@chilemagic: скидання пробілу між / $ + / і одночасно працює лише зі старими перлами. Останні perls змінили аналізатор, щоб відкрити можливість додавати нові модифікатори регулярних
виразів

@ msh210: Працює для деяких магічних змінних, але не для тих, що базуються на
пробілі

6

JavaScript (ES6), 66 61 байт

Збережено 5 байт завдяки @Neil

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

Я не вважаю, що регулярний вигріб ще не можна пограбувати. Дивно, але найкоротше, що я можу придумати, щоб видалити передню частину назад, - це байт довше:

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
Мені байдуже, чи це не гольф, це прекрасний вираз.
Ніл

Хоча я щойно помітив, що ви можете використовувати |.$/,"$1$2"для збереження 5 байт.
Ніл

@Neil Дякую за пораду!
ETHproductions

2

ш + гну сед, 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

Луа, 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

Перл, 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 до кінця: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
Підвищена більшість в метах говорить, що ви можете зберегти байт з допомогою
каррінгу

@Cyoce, схоже, що в цьому випадку каррі не спрацьовують ( s->j->{...}). Я думаю, що або Java це не дуже підтримує, або я неправильно налаштовую.
GamrCorps

Мови, що складаються, напевно, мають труднощі з каррінгом через функції першого класу
CalculatorFeline

@GamrCorps Я перевірю, чи зможу я змусити його працювати, коли
повернусь

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;}

Тестер:

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

Scala, 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]")," "),".")}

Тестер:

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

1

Діалог APL, 77 45 42 байт

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

t[]Літери t з індексами ...
t←⌽⍞ t отримує зворотне введення тексту
i←⍳⍴t i отримує індекси довжиною t
/¨⊂i кратне (3) булеві виділення елементів i :
1. (t∊'aeiou')булева, де голосна
2. (' '=t)булева, де пробіл
3. 1все ∪∊унікальне із занесеного ( вирівняно) 3 вибору
⌽⎕↓⌽падають останні оцінені символи (те саме, що (-⎕)↓)
⌽i~ обертають решта індексів після видалення деяких


Оригінальна відповідь:

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

Ем, так, це важко читати. В основному прямий переклад ОП на APL:

  1. Зворотний вхід.
  2. Якщо потрібна довжина більша або дорівнює кількості введеного (перевернутого) вхідного рядка, повертайте аргументований (зворотний) аргумент.
  3. В іншому випадку, якщо аргумент має якусь голосну, видаліть першу (тобто останню) та рекурсивно викликайте те, що залишилося.
  4. В іншому випадку, якщо аргумент має пробіл, видаліть перший (тобто останній) і рекурсивно зателефонуйте на те, що залишилося.
  5. В іншому випадку видаліть перший (тобто останній) символ і зателефонуйте рекурсивно на те, що залишилося.

0

Математика, 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)

неозорий з поясненням

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))])}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.