Crunch voyelles hors d'une chaîne


22

Description de la tâche

Parfois, vous devez vraiment adapter quelque chose que vous écrivez dans un petit espace. Il peut être tentant de laisser tomber les voyelles et les mots - et à défaut, qui a vraiment besoin d'espaces? Thssprfctlrdbl!

Écrivez une fonction ou un programme qui supprime les voyelles minuscules aeiou, puis les espaces, puis tous les caractères d'une chaîne d'entrée . De plus, chaque fois que vous supprimez un personnage, il doit être le personnage le plus à droite éligible pour la suppression. Il doit répéter ce processus jusqu'à ce que la chaîne ne dépasse pas une certaine longueur d'entrée donnée .

† "C'est parfaitement lisible!" Mais si vous lisez cette note, ce n'est probablement pas vraiment ... :)

Exemples

Ici, vous pouvez voir ce processus appliqué pour des tailles d'entrée successivement plus petites:

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.)

Après avoir réduit la chaîne à 17 caractères, nous manquons de voyelles à supprimer, donc le caractère suivant que nous supprimons est l'espace le plus à droite; lorsque nous frappons 14 caractères, nous avons supprimé toutes les voyelles et les espaces, donc nous commençons simplement à grignoter la chaîne de droite à gauche.

Voici un code Python pseudocode qui résout ce défi:

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

Règles

  • Il s'agit de , donc le code le plus court en octets l'emporte.

  • La chaîne d'entrée sera constituée des caractères ASCII imprimables de l'espace ( , décimal 32) jusqu'au tilde inclus ( ~, décimal 126). Il n'y aura pas de voyelles majuscules AEIOUdans la chaîne. En particulier, aucun Unicode, onglet ou nouvelle ligne ne sera impliqué.

  • Appelez la chaîne d'entrée s et la longueur cible d'entrée t . Alors 0 <t ≤ longueur ( s ) ≤ 10000 est garanti. (En particulier, la chaîne d'entrée ne sera jamais vide. Si t = longueur ( s ), vous devez simplement renvoyer la chaîne non modifiée.)

Cas de test

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
Est yune voyelle?
edc65

1
Je ne peux pas croire que j'ai oublié d'expliquer cela! Non, aeiousont des voyelles, et AEIOUne se produiront pas, pour plus de simplicité. (Le tout en majuscules / minuscules n'est pas ce sur quoi je veux me concentrer.) J'ai ajouté une clarification.
Lynn

1
Très beau défi!
Luis Mendo

@ edc65 N'oubliez pas w(par exemple, dans le mot co w , west une voyelle!) Bien sûr, c'est réglé pour celle-ci, mais pour les cas où il n'est pas indiqué que l'ensemble des voyelles est aeiou, vous devez parfois inclure yet w. : -O
corsiKa

Sans rapport avec le golf, mais pensez à la for index, char in enumerate(string)place de la range(len(str))construction
Jeremy Weirich

Réponses:


6

MATL , 20 octets

t11Y2mEG32=+K#Si:)S)

Essayez-le en ligne!

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 octets

Comprend +4 pour -Xlpi(-X peut être omis mais laisse des avertissements moches sur STDERR)

Exécutez avec le numéro après l' -ioption et l'entrée sur STDIN (prend également en charge plusieurs lignes). par exempleperl -Xlpi50 crunch.pl <<< "Duis commodo scelerisque ex, ac consectetur metus rhoncus."

crunch.pl:

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

Vous n'avez pas besoin d'espace entre /$+/etwhile
hmatt1

Je pense que vous rasez un octet en utilisant un ^ I (tabulation) au lieu de "^ I". (Non testé.)
msh210

@chilemagic: supprimer l'espace entre / $ + / et ne fonctionne qu'avec les anciennes perles. Des perls récentes ont changé l'analyseur pour garder ouverte la possibilité d'ajouter de nouveaux modificateurs d'expression régulière (comme le modificateur aw)
Ton Hospel

@ msh210: Fonctionne pour certaines variables magiques, mais pas pour celles basées sur les espaces blancs
Ton Hospel

6

JavaScript (ES6), 66 61 octets

5 octets enregistrés grâce à @Neil

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

Je ne pense pas que le regex soit jouable au golf plus loin. Étonnamment, le plus court que je puisse trouver pour supprimer l'avant-arrière est un octet plus long:

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

Tentative plus intéressante (ES7), 134 octets

(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``

Cela utilise une approche similaire à la réponse MATL.


1
Je me fiche que ce ne soit pas jouable au golf, c'est une belle expression régulière.
Neil

Bien que je viens de remarquer que vous pouvez utiliser |.$/,"$1$2"pour économiser 5 octets.
Neil

@Neil Merci pour le conseil!
ETHproductions

2

sh + gnu sed, 78 61

Fournissez la chaîne à STDIN, la longueur comme premier argument.

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 octets

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())

Prend l'entrée comme arguments de ligne de commande, au format lua crunch.lua 10 "This is a string", avec la sortie Ths sstrng.

Explication:

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

Supprimer à droite ajoute une tonne de personnages, peut-être y a-t-il une meilleure façon de le faire.

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

Utilisez -ipour saisir le numéro. Il est de 65 caractères plus 3 pour la i, pet lsur la ligne de commande.

Courir avec:

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

Vous pouvez utiliser à la y///cplace de lengthet vous pouvez déplacer la boucle while à la fin:s///||s///||s///while$^I<y///c
andlrc

1

Java 8, 303 octets

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

C'est bien trop long. J'essaierai de le raccourcir bientôt. Ce serait beaucoup plus court si java avait une méthode pour inverser les chaînes et les remplacements en arrière.

Testez avec les éléments suivants:

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
La majorité écrasante sur les méta dit que vous pouvez enregistrer un octet avec le curry
Cyoce

@Cyoce il semble que le curry ne fonctionne pas dans ce cas ( s->j->{...}). Je pense que Java ne le supporte pas très bien ou je le configure mal.
GamrCorps

Les langues compilées ont probablement du mal à curry en raison des fonctions de première classe
CalculatorFeline

@GamrCorps Je vais vérifier et voir si je peux le faire fonctionner quand je rentre à la maison
Cyoce

1

C #, 180 octets

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

Testeur:

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 octets

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

Testeur:

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

1

Dyalog APL, 77 45 42 octets

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

t[]Lettres de t avec indices ...
t←⌽⍞ t obtient une entrée de texte inversée
i←⍳⍴t i obtient des indices de longueur de t
/¨⊂i multiples (3) sélections booléennes des éléments de i :
1. (t∊'aeiou')booléen où voyelle
2. (' '=t)booléen où espace
3. 1tout ∪∊unique de l'enrôlé ( aplati) 3 sélections
⌽⎕↓⌽suppriment les derniers caractères évalués en entrée (les mêmes que (-⎕)↓)
⌽i~inversent les indices restants après avoir supprimé certains


Réponse originale:

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

Ehm, oui, c'est un peu difficile à lire. Fondamentalement, la traduction directe d'OP en APL:

  1. Entrée inversée.
  2. Si la longueur requise est plus longue ou égale au nombre de chaînes d'entrée (inversées), retournez l'argument inversé (inversé).
  3. Sinon, si l'argument a une voyelle, supprimez la première (c'est-à-dire la dernière) et appelez récursivement ce qui reste.
  4. Sinon, si l'argument a de l'espace, supprimez le premier (c'est-à-dire le dernier) et appelez récursivement ce qui reste.
  5. Sinon, supprimez le premier (c'est-à-dire le dernier) caractère et appelez récursivement ce qui reste.

0

Mathematica, 201 octets

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&]

Il doit y avoir un meilleur moyen que cela ..


0

R, 169 143 octets

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))])}

* modifier les 36 octets enregistrés par réécriture avec utf8ToInt-> intToUtf8pas de conversions strstplitetpaste0(...,collapse)

non golfé avec explication

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))])}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.