Хрустящие гласные из струны


22

Описание задания

Иногда вам действительно нужно разместить что-то, что вы пишете, на небольшом пространстве. Может быть заманчиво отбросить гласные и без них - и если это не удастся, кому действительно нужны пробелы? 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 ≤ length ( s ) ≤ 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 (символ табуляции) вместо «^ I». (Не проверено.)
msh210

@chilemagic: выбрасывая пробел между / $ + / и в то время как работает только со старыми perl. Последние perls изменили парсер, чтобы оставить возможность добавлять новые модификаторы регулярных выражений (например, модификатор aw)
Ton Hospel

@ 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

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 до конца: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

@Cyoce кажется, что карри не работает в этом случае ( 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

Дьялог АПЛ, 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)

безрассудный с объяснением

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.