Compter et épeler

26

Écrivez un programme qui prend en entrée une chaîne qui produit une chaîne avec les propriétés suivantes.

  • Si un caractère de la chaîne est une lettre majuscule (ASCII 41-5A), alors le caractère est remplacé par une chaîne contenant chaque lettre jusqu'à et y compris la lettre d'origine en majuscule. Par exemple, si la chaîne d'entrée estI , alors la sortie le sera ABCDEFGHI.
  • De même, si un caractère est une lettre minuscule (ASCII 61-7A), alors le caractère est remplacé de la même manière. iserait remplacé par abcdefghi.
  • Si un caractère est un nombre (ASCII 30-39), alors le caractère est remplacé par chaque nombre à partir de 0 et en comptant jusqu'au nombre.
  • Si l'entrée contient des caractères individuels concaténés, les séquences de remplacement sont concaténées ensemble.
  • Tous les autres caractères sont imprimés sans modification.

Exemples d'entrées (séparées par des lignes vides)

AbC123

pi=3.14159

Hello, World!

Exemples de sorties

AabABC010120123

abcdefghijklmnopabcdefghi=0123.0101234010123450123456789

ABCDEFGHabcdeabcdefghijklabcdefghijklabcdefghijklmno, ABCDEFGHIJKLMNOPQRSTUVWabcdefghijklmnoabcdefghijklmnopqrabcdefghijklabcd!

C'est du golf de code, les gars. Des règles standard s'appliquent. Le code le plus court en octets gagne.


Pour voir le classement, cliquez sur "Afficher l'extrait de code", faites défiler vers le bas et cliquez sur "► Exécuter l'extrait de code". Extrait créé par Optimizer.

Arcturus
la source
10
Idée pour une suite: défaire cette transformation.
ETHproductions
2
@ETHproductions Peut-être, bien que la voie ici me semble meilleure car elle peut prendre n'importe quelle entrée; Et si à l'inverse l'entrée était Hello, World!?
Arcturus
Faut-il prendre en charge les caractères NUL (ascii 0x00) dans la chaîne d'entrée?
nimi
@Eridan dans un tel cas, le code devrait imprimer une erreur ou, pour une touche amusante, effectuer la transformation ci-dessus. C'est-à-dire, f (f (entrée)) == entrée. Je ne crois pas qu'il soit possible pour une entrée alphanumérique de désobéir à cette relation.
Jake
1
C'est tout à fait vrai - je fais l'hypothèse que "si une chaîne PEUT ÊTRE le résultat de la transformation, inversez-la. Sinon, appliquez la transformation." - c'est votre défi, vous pouvez spécifier toutes les règles que vous choisissez tant (a) qu'elles sont cohérentes et (b) qu'elles sont vérifiables et ne nécessitent pas une toute nouvelle branche des mathématiques à résoudre. Note annexe: Irradier (b) serait intéressant; vous ne savez jamais quand quelqu'un révolutionnera accidentellement l'informatique en proposant un algorithme de temps polynomial pour un problème NP - ce qui est en fait raisonnable ici, tant qu'il économise 4 octets.
Jake

Réponses:

11

Pyth, 19 octets

sXzsJ+rBG1jkUTs._MJ

Essayez-le en ligne: démonstration ou suite de tests

Explication

sXzsJ+rBG1jkUTs._MJ
      rBG1            the list ["abc...xyz", "ABC...XYZ"]
     +    jkUT        appends the string "0123456789"
    J                 save this list of 3 strings in J
   sJ                 join the strings in J
               ._MJ   create all prefixes of the strings in J
              s       and combine them to one list
 XzsJ         s._MJ   translate the input string, chars from sJ
                      get translated to the correct prefix,
                      chars that don't appear in sJ don't get translated
s                     join all resulting translation strings
Jakube
la source
8

Python 2.7, 100 98 96 octets

a=[]
for c in raw_input():d=ord(c);a+=range(max(d&96|1,48),d)*c.isalnum()+[d]
print bytearray(a)
xsot
la source
7

TeaScript , 24 octets 26 28

TeaScript est JavaScript pour le golf

xl(#(i=lN()1)h(ii(l)+1))

Plutôt court

Essayez-le en ligne

Explication

x.l(#            // Loops through each character of the string

     (i=l.N()1)  // Determines whether a character is alphanumeric
                 // Will return A-Z, a-z or 0-9 depending on result
                 // Assigns to variable i

     .h(         // Get characters up to...
        i.i      // where the character is in "i"
     ) + 1       // Increased by one
)
Downgoat
la source
6

Rubis, 137 87 82 76 67 55 octets

Non golfé, mais vous pouvez voir le motif.

$><<gets.gsub(/[a-z0-9]/i){[*" 0Aa"[$&.ord/32]..$&]*""}

Edit: golfé jusqu'à un seul regex.

Edit 2: avait beaucoup d'espaces supplémentaires.

Edit 3: Merci à manatwork pour jouer au golf 12 octets!

Peter Lenkefi
la source
1
$><<gets.gsub(/[a-z0-9]/i){[*" 0Aa"[$&.ord/32]..$&]*""}
manatwork
@manatwork Merde c'est intelligent!
Peter Lenkefi
4

Python 2, 145 140 133 103 102 Octets

Une fonction anonyme pas si élégante utilisant la compréhension de liste. J'ai l'impression que la logique devrait être beaucoup plus courte, je vais essayer de comprendre quelque chose.

lambda k:''.join([c,`map(chr,range(48+17*(c>'@')+32*(c>'`'),ord(c)+1))`[2::5]][c.isalnum()]for c in k)

Doit être donné un nom à utiliser, c'est-à-dire f=...

Kade
la source
@Mego Oh, haha! Pas de soucis :)
Kade
4

Haskell, 95 91 86 60 octets

c#(a:o:r)|c<a||c>o=c#r|1<2=[a..c]
c#_=[c]
f=((#"AZaz09")=<<)

Exemple d'utilisation: f "pi=3.14159"->"abcdefghijklmnopabcdefghi=0123.0101234010123450123456789"

Comment cela fonctionne: copiez chaque caractère c dans la chaîne d'entrée à moins que c ne soit entre A/ Z, a/ zou 0/ 9et si c'est le cas, prenez la liste des[<first char in pair> ... <c>] .

Edit: @Zgarb a enregistré de nombreux octets. Merci!

nimi
la source
Je pense que vous pouvez définir c#_=[c]et ignorer tcomplètement.
Zgarb
@Zgarb: Oui en effet, et sc'est aussi superflu. Merci beaucoup!
nimi
4

JavaScript (ES6), 143 138 octets

Utilise des comparaisons de chaînes pour tester les caractères à utiliser.

s=>s.replace(/[A-Z0-9]/gi,c=>(a=btoa`Ó]·ã»óÖq×£Y§¢«²Û¯Ã³`,(c>'Z'?a:a.toUpperCase()).split``.filter(x=>x<=c&(x>'9'|c<'A')).join``))

Démo en ligne. Testé dans Firefox et Chrome.

Edit: enregistré 5 octets en remplaçant a='0123456789abcdefghijklmnopqrstuvwxyz'par

a=btoa`Ó]·ã»óÖq×£Y§¢«²Û¯Ã³`
intrépide
la source
3

PHP, 146 octets

Golfé

function f($n,&$l){for(;$c=$n[$r],$b=0,$d=ord($c);$r++,$b?:$l.=$c)foreach([58=>48,91=>65,123=>97] as $m=>$i)while($d<$m&&$d>=$i)$b=$l.=chr($i++);}

Révision 1: mettez les plages ord directement dans foreach. incrémenté plage max ord et changé $d<=$men $d<$m. utiliser forpour itérer les caractères au lieu de foreachet str_split. Tout supprimé {}en déplaçant le code dansfor

Non golfé

function f($input,&$output){
foreach (str_split($input) as $char){
  $ord = ord($char);
  $ords = [57=>48,90=>65,122=>97];
  $b = 0;
  foreach ($ords as $max=>$min){
     while ($ord<=$max&&$ord>=$min){
         $b = $max;
         $output .= chr($min);
         $min++;
     }
  }
  $b ?: $output.=$char;
}
};

$output = NULL;
$input = "pi=3.141592";
f($input,$output);
echo $output;

Explication: fractionner la chaîne en tableau. Si la valeur ascii tombe dans une plage (pour az, AZ, 0-9), incrémentez un compteur du min de la plage à la valeur ascii du caractère, en ajoutant chaque valeur jusqu'à ce que vous atteigniez la valeur ascii du caractère.

Je suis passé &$vardonc la sortie se fait par référence plutôt que parreturn

Roseau
la source
Il n'est pas nécessaire que la variable $ z contienne le tableau de plages, vous pouvez mettre le tableau littéral directement dedans foreach.
manatwork
Vous avez essayé d'utiliser range()? pastebin.com/k2tqFEgD
manatwork
@manatwork, j'ai changé de déclaration $zet apporté d'autres modifications. range()serait probablement mieux. Je pourrais essayer quelque chose avec la gamme plus tard.
Reed
En utilisant range, j'ai eu function f($n,&$l){$o=['a'=>'z','A'=>'Z','0'=>'9'];foreach(str_split($n) as $c){$b=0;foreach($o as $m=>$x)!($c>$m&&$c<=$x)?:$b=$l.=implode(range($m,$c));$b?:$l.=$c;}}, qui était 166.
Reed
1
Oui, après votre réécriture à 146 caractères, l'utilisation range()est moins avantageuse. Mais cela 166 est trop long quand même: le $ o pour le littéral du tableau est de retour, il y a des espaces supplémentaires autour des asmots-clés, join()est un alias pour implode(). (?. Vérifié le code pastebin je montre une autre plus tôt lié possibilité de stocker les points d' extrémité de gamme) En ce qui concerne votre solution 146 caractères, vous pouvez déplacer l'affectation à $ c à l' intérieur de l' ord()appel: $d=ord($c=$n[$r]).
manatwork du
2

Python, 143 octets

lambda s:''.join(map(chr,sum(map(lambda a,r=range:r(65,a+1)if 64<a<97else r(97,a+1)if 96<a<123else r(48,a+1)if 47<a<58else[a],map(ord,s)),[])))

Essayez-le en ligne

Mego
la source
2
Vous pouvez utiliser z = range pour enregistrer 4 octets.
Arcturus
1
Je suis presque sûr que vous pouvez remplacer les retraits à double espace par un seul onglet, ce qui vous permettrait d'économiser quelques octets
Fund Monica's Lawsuit
2

Perl 6, 101 octets

Voici un premier passage:

sub MAIN($_ is copy){
  s:g/<[0..9]>/{(0..$/).join}/;
  s:g/<[a..z]>/{('a'..~$/).join}/;
  s:g/<[A..Z]>/{('A'..~$/).join}/;
  .say
}
sub MAIN($_ is copy){s:g/<[0..9]>/{(0..$/).join}/;s:g/<[a..z]>/{('a'..~$/).join}/;s:g/<[A..Z]>/{('A'..~$/).join}/;.say}

119


Utiliser .transsur $_pour supprimer is copy.

sub MAIN($_){
  .trans(
    /\d/       => {(0..$/).join},
    /<[a..z]>/ => {('a'..~$/).join},
    /<[A..Z]>/ => {('A'..~$/).join}
  ).say
}
sub MAIN($_){.trans(/\d/=>{(0..$/).join},/<[a..z]>/=>{('a'..~$/).join},/<[A..Z]>/=>{('A'..~$/).join}).say}

106


Agissez @*ARGSdirectement au lieu de définir un MAINsous - marin.
(sinon identique à l'exemple précédent)

@*ARGS[0].trans(/\d/=>{(0..$/).join},/<[a..z]>/=>{('a'..~$/).join},/<[A..Z]>/=>{('A'..~$/).join}).say

101

Brad Gilbert b2gills
la source
2

Scala, 111 91 octets

val f=(_:String).flatMap(x=>if(x.isDigit)('0'to x)else if(x.isUpper)('A'to x)else('a'to x))
Martin Seeler
la source
Cela échoue pour pi=3.14159. La solution pourrait-elle être val f=(_:String).flatMap(x:String=>if(x.isDigit)('0'to x)else if(x.isUpper)('A'to x)else if(x.isLower)('a'to x)else x.toString)pour un énorme 128 caractères?
Leonardo
2

Julia, 102 98 90 84 octets

s->join([(i=Int(c);join(map(Char,(64<c<91?65:96<c<123?97:47<c<58?48:i):i)))for c=s])

Cela crée une fonction sans nom qui accepte une chaîne et renvoie une chaîne.

Non golfé:

function f(s::AbstractString)
    # For each character in the input, get the codepoint and construct
    # a range of codepoints from the appropriate starting character to
    # the current character, convert these to characters, and join them
    # into a string
    x = [(i = Int(c);
          join(map(Char, (isupper(c) ? 65 :
                          islower(c) ? 97 :
                          isdigit(c) ? 48 : i):i))
         ) for c in s]

    # Join the array of strings into a single string
    return join(x)
end
Alex A.
la source
2

PowerShell, 155 octets

($args-split''|%{$b=$_;switch([int][char]$_){{$_-in(65..90)}{[char[]](65..$_)}{$_-in(97..122)}{[char[]](97..$_)}{$_-in(48..57)}{0..$b}default{$b}}})-join''

Techniquement, une ligne, et PowerShell est tout à propos de ceux-ci ;-)

Fractionne l'entrée, redirige cela en ForEach-Objectboucle, active la valeur entière du caractère cast, puis génère une nouvelle char[]plage appropriée. Notez que nous devons dépenser des octets pour définir une variable temporaire$b car l'acte de transtyper l'entrée$_ dans l'instruction switch signifie que nous ne pouvons pas simplement continuer à utiliser$_ ou nous obtiendrons une sortie géniale.

EDIT - Je dois souligner que cela entraînera des erreurs puisque le premier objet introduit %{...}est un objet nul. Étant donné que STDERR est ignoré par défaut , cela ne devrait pas être un problème. Si c'est un problème, changez le premier bit ($args-split''-ne''|...pour éliminer l'objet nul.

AdmBorkBork
la source
2

JavaScript (ES6), 340 258 273 271 octets

a=s=>{s=s.split``;Q=x=>x.toUpperCase();A="ABCDEFGHIJKLMNOPQRSTUVWXYZ";D="0123456789";f="";for(i=0;i<s.length;i++){j=s[i];c="to"+(Q(j)==j?"Upper":"Lower")+"Case";j=Q(j);if(q=A.search(j)+1)f+=g=A.slice(0,q)[c]();else if(q=D.search(j)+1)f+=g=D.slice(0,q);else f+=j}return f}
Conor O'Brien
la source
Vous pouvez utiliser une chaîne de modèle `` pour le fractionnement au lieu de ("")et f=i=""dans la boucle for. Vous pourrez peut-être enregistrer quelques octets supplémentaires.
intrepidcoder
@intrepidcoder Le premier fonctionnerait. Je vérifie la seconde.
Conor O'Brien
2

C (269 octets)

(saut de ligne ajouté pour plus de clarté)

#include<stdio.h>
#define F(x,y,z)if(c>=T[0][x]&&c<=T[1][y]){z}
#define L(x,y)for(i=0;i<x;++i){y}
main(){int c,i,n;char o,*T[]={"0Aa","9Zz"};while((c=getchar())!=EOF)
{F(0,2,L(3,F(i,i,o=T[0][i],n=++c-o;L(n,putchar(o++));break;))else putchar(c);)}}

Non golfé

#include<stdio.h>
int main(void)
{
  int c, i, n;
  char output;
  char *char_table[] = {"0Aa", "9Zz"};

  while ((c = getchar()) != EOF) {
    if (c < '0' || c > 'z') {
      putchar(c);
    } else {
      for (i = 0; i < 3; ++i) {
        if (c >= char_table[0][i] && c <= char_table[1][i]) {
          output = char_table[0][1];
          n = c - output;
          break;
        }
      }
      for (i = 0; i <= n; ++i) {
        putchar(output);
        ++output;
      }
    }
  }
  return(0);
}
musarithmie
la source
2

Perl 5 , 66 61 (51 octets + 1) 52

La combinaison des expressions rationnelles avec des opérateurs conditionnels a bien fonctionné dans ce cas.
Avec une jointure Utilisation de la carte pour combiner les plages dans un tableau.

say map{(/\d/?0:/[A-Z]/?A:/[a-z]/?a:$_)..$_}split//

Tester

$ echo "A0C1.a3c_2!" |perl -M5.010 -n count_and_spell_up.pl
A0ABC01.a0123abc_012!

Explication

say                # print output
  map{             # loop through the array that's at the end of the other mustache. 
                   # outputs an array. 
     (
        /\d/?0            # if $_ is a digit then 0
          :/[A-Z]/?A      # else, if it's an uppercase character then A
             :/[a-z]/?a   # else, if it's a lowercase character then a
               :$_        # else the current character
     )..$_         # generate a sequenced string of characters 
                   # that ends with the magic variable $_ 
                   # ($_ is currently a character from the array)
  }split//     # split the magic variable $_ (currently the input string)
               # to an array of characters
LukStorms
la source
1

JavaScript (ES7), 125 octets

Il y avait déjà deux réponses JS se concentrant sur l'encodage des chaînes, j'ai donc décidé d'opter pour une approche plus algorithmique en utilisant String.fromCharCode():

x=>x.replace(/[^\W_]/g,z=>(c=z.charCodeAt(),f=c<65?48:c<97?65:97,String.fromCharCode(...[for(i of Array(c-f).keys())i+f])+z))

Un avantage de l'utilisation de cette méthode est qu'elle prend n'importe quelle quantité de codes de caractères, donc joinla liste n'est pas nécessaire. Cela s'est avéré plus court que toute autre technique, donc je suis satisfait du résultat.

ETHproductions
la source
1

MUMPS, 131 octets

u(l,h) i l'>a,a'>h f j=l:1:a s o=o_$C(j),f=0
    q
t(s) f i=1:1:$L(s) s a=$A(s,i),f=1 d u(48,57),u(65,90),u(97,122) s:f o=o_$C(a)
    q o

J'ai réussi à enregistrer quelques bons octets ici grâce à la portée dynamique de MUMPS . Voici une version non équivalente à peu près équivalente, que j'aimerais sûrement souligner la syntaxe, si seulement le support du module MUMPS Prettify était disponible .

convert(str) ;
    new asciiCode,flag,i,output
    for i=1:1:$LENGTH(str) do
    . set asciiCode=$ASCII(str,i)
    . set flag=1
    . do helper(48,57)
    . do helper(65,90)
    . do helper(97,122)
    . if 'flag do
    . . set output=output_$CHAR(asciiCode)
    quit
helper(low,high) ;
    if low'>asciiCode,asciiCode'>high do
    . for code=low:1:asciiCode do
    . . set output=output_$CHAR(code)
    . . set flag=0
    quit
senshin
la source
1

Perl 6, 78 77 octets

@*ARGS[0].trans(/\d/=>{[~] 0..$/},/<:L>/=>{[~] samecase("a",~$/)..~$/}).say
Raccourcis clavier
la source
Je savais que cela pourrait être raccourci en combinant les cas 'a'..'z'et 'A'..'Z', j'aurais dû essayer plus fort.
Brad Gilbert b2gills,
Je recommande d'ajouter <!-- language-all: lang-perl6 -->juste après ## Perl 6pour qu'il soit correctement mis en évidence. (Le changement est déjà en attente sur cette réponse)
Brad Gilbert b2gills
Vous pouvez basculer {[~](0..$/)}vers celui {[~] 0..$/}qui permettra d'économiser un octet.
Brad Gilbert b2gills
0

Mathematica, 102 octets

FromCharacterCode@Flatten[Which[64<#<91,65,96<#<123,97,47<#<58,48,1>0,#]~Range~#&/@ToCharacterCode@#]&

Tant pis...

LegionMammal978
la source
0

CJam, 32 31 octets

q_'[,_el^A,s+26/ff{_@#)<}:s\.e|

Essayez-le en ligne dans l' interpréteur CJam .

Comment ça marche

q_    e# Push two copies of the user input.
'[,   e# Push the string of all ASCII characters up to Z.
_el   e# Push a copy and convert it to lowercase.
^     e# Perform symmetric difference this keeps only letters.
A,s+  e# Append the string "0123456789".
26/   e# Split the result into chunks of length 26.
ff{   e# For each character from input: For each chunk:
  _@  e#   Copy the chunk and rotate the character on top of it.
  #   e#   Push the index of the character in the string (-1 for not found).
  )<  e#   Increment and keep that many characters from the left of the chunk.
      e#   This pushes "" for index -1.
}
:s    e# Flatten the resulting arrays of strings.
      e# The results will be empty strings iff the character wan't alphanumeric.
\     e# Swap the result with the input string.
.e|   e# Perform vectorized logical OR.
Dennis
la source
0

Python 2, 135 117 octets

s=''
for c in raw_input():
 b=ord(c);e=b+1
 if c.isalnum():
  b=max(b&96,47)+1
 for i in range(b,e):s+=chr(i)
print s
TFeld
la source
0

PHP - 291 octets

Passez la chaîne à GET["s"].

<?php $s=$_GET["s"];$m="array_map";echo implode($m(function($v){$i="in_array";$l="implode";$r="range";global$m;$a=ord($v);if($i($a,$r(48,57)))$v=$l($m("chr",$r(48,$a)));if($i($a,$r(65,90)))$v=$l($m("chr",$r(65,$a)));if($i($a,$r(97,122)))$v=$l($m("chr",$r(97,$a)));return$v;},str_split($s)));
indéfini
la source
0

C #, 251 201 184 157 154 octets

using System;class c{static void Main(string[] i){foreach(var c in i[0])for(var x=c>64&c<91?'A':c>96&c<123?'a':c>47&c<58?'0':c;x<=c;)Console.Write(x++);}}

modifier: Strike! Plus court que PowerShell;)

Stephan Schinkel
la source
1
pouvez-vous faire string[]i?
Erik the Outgolfer