Contando e soletrando

26

Escreva um programa que tenha como entrada uma sequência que emita uma sequência com as seguintes propriedades.

  • Se um caractere na string for uma letra maiúscula (ASCII 41-5A), o caractere será substituído por uma string contendo todas as letras até e incluindo a letra original em maiúsculas. Por exemplo, se a sequência de entrada for I, a saída seria ABCDEFGHI.
  • Da mesma forma, se um caractere for uma letra minúscula (ASCII 61-7A), o caractere será substituído da mesma maneira. iseria substituído por abcdefghi.
  • Se um caractere é um número (ASCII 30-39), o caractere é substituído por todos os números começando 0e contando até o número.
  • Se a entrada contiver caracteres individuais concatenados, as seqüências de substituição serão concatenadas juntas.
  • Todos os outros caracteres são impressos sem modificação.

Entradas de amostra (separadas por linhas em branco)

AbC123

pi=3.14159

Hello, World!

Saídas de amostra

AabABC010120123

abcdefghijklmnopabcdefghi=0123.0101234010123450123456789

ABCDEFGHabcdeabcdefghijklabcdefghijklabcdefghijklmno, ABCDEFGHIJKLMNOPQRSTUVWabcdefghijklmnoabcdefghijklmnopqrabcdefghijklabcd!

Isso é código de golfe, pessoal. Aplicam-se regras padrão. O menor código em bytes vence.


Para ver a tabela de classificação, clique em "Mostrar trecho de código", role para baixo e clique em "► Executar trecho de código". Snippet criado pelo Optimizer.

Arcturus
fonte
10
Idéia para uma sequência: desfaça essa transformação.
ETHproductions
2
@ETHproductions Talvez, embora o caminho aqui pareça melhor para mim, pois pode receber qualquer entrada; e se no inverso a entrada fosse Hello, World!?
Arcturus
Temos que suportar caracteres NUL (ascii 0x00) na string de entrada?
nimi
@Eridan, nesse caso, o código deve imprimir um erro ou, para um toque divertido, executar a transformação acima. Ou seja, f (f (entrada)) == entrada. Não acredito que seja possível que qualquer entrada alfanumérica desobedeça essa relação.
Jake
1
Isso é inteiramente verdade - suponho que "se uma string PODE SER o resultado da transformação, inverta-a. Caso contrário, aplique a transformação". - é seu desafio, você pode especificar todas as regras que escolher, desde que (a) sejam consistentes e (b) sejam verificáveis ​​e não exijam que um novo ramo da matemática seja resolvido. Nota lateral: Irradicar (b) seria interessante; você nunca sabe quando alguém revolucionará acidentalmente a ciência da computação criando um algoritmo de tempo polinomial para um problema de NP - o que é realmente razoável aqui, desde que ele economize 4 bytes.
Jake

Respostas:

11

Pitão, 19 bytes

sXzsJ+rBG1jkUTs._MJ

Experimente on-line: Demonstration or Test Suite

Explicação

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

Python 2.7, 100 98 96 bytes

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

TeaScript , 24 bytes 26 28

TeaScript é JavaScript para jogar golfe

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

Bem curto

Experimente online

Explicação

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

Ruby, 137 87 82 76 67 55 bytes

Ungolfed, mas você pode ver o padrão.

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

Edit: reduziu para apenas um regex.

Edit 2: tinha muitos espaços extras.

Edit 3: Graças ao manatwork para jogar golfe com 12 bytes!

Peter Lenkefi
fonte
1
$><<gets.gsub(/[a-z0-9]/i){[*" 0Aa"[$&.ord/32]..$&]*""}
manatwork
@manatwork Porra, isso é inteligente!
27416 Peter Lenkefi
4

Python 2, 145 140 133 103 102 Bytes

Uma função anônima não tão elegante usando compreensão de lista. Eu sinto que a lógica deve ser muito menor, vou tentar descobrir alguma coisa.

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

Deve ser dado um nome a ser usado, ou seja, f=...

Kade
fonte
@Mego Oh, haha! Não se preocupe :)
Kade
4

Haskell, 95 91 86 60 bytes

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

Exemplo de uso: f "pi=3.14159"->"abcdefghijklmnopabcdefghi=0123.0101234010123450123456789"

Como funciona: copie todos os caracteres c na string de entrada, a menos que c esteja entre A/ Z, a/ zou 0/ 9e, se for o caso, faça a lista de [<first char in pair> ... <c>].

Edit: @Zgarb salvou muitos bytes. Obrigado!

nimi
fonte
Eu acho que você pode definir c#_=[c]e pular tcompletamente.
Zgarb 27/10/2015
@ Zgarb: Sim, de fato e depois stambém é supérfluo. Muito obrigado!
N /
4

JavaScript (ES6), 143 138 bytes

Usa comparações de strings para testar quais caracteres usar.

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

Demonstração online. Testado no Firefox e Chrome.

Editar: salvou 5 bytes substituindo a='0123456789abcdefghijklmnopqrstuvwxyz'por

a=btoa`Ó]·ã»óÖq×£Y§¢«²Û¯Ã³`
intrepidcoder
fonte
3

PHP, 146 bytes

Golfe

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

Revisão 1: coloque os intervalos ord diretamente no foreach. o intervalo ord ord incrementado e alterado $d<=$mpara $d<$m. usando forpara iterar caracteres em vez de foreache str_split. Removido tudo {}movendo o código parafor

Ungolfed

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;

Explicação: divida a sequência em matriz. Se o valor ascii cair em um intervalo (para az, AZ, 0-9), aumente um contador do mínimo do intervalo para o valor ascii do caractere, acrescentando cada valor até você atingir o valor ascii do caractere.

Como passei, &$vara saída é feita por referência e não por umreturn

Reed
fonte
Não é necessário que a variável $ z retenha a matriz de intervalos, você pode colocar a matriz literalmente diretamente foreach.
manatwork
Tentou usar range()? pastebin.com/k2tqFEgD
manatwork
@manatwork, mudei de declaração $ze fiz algumas outras alterações. range()provavelmente seria melhor. Eu poderia tentar algo com alcance mais tarde.
Reed
Usando range , eu consegui 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;}}, que era 166.
Reed
1
Sim, depois de reescrever para 146 caracteres, o uso range()é menos benéfico. Mas esse 166 é muito longo, mesmo assim: o $ o para o literal da matriz está de volta, há espaços extras em torno das aspalavras - chave e join()é o pseudônimo de implode(). (?. Verificado o código pastebin I ligada anteriormente Shows outra possibilidade para armazenar os parâmetros de intervalo) Quanto à sua solução de 146 caracteres, você pode mover a atribuição para $ c dentro da ord()chamada: $d=ord($c=$n[$r]).
manatwork
2

Python, 143 bytes

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)),[])))

Experimente online

Mego
fonte
2
Você pode usar z = range para salvar 4 bytes.
Arcturus
1
Certeza que você pode substituir os travessões espaço duplo com uma única guia, que você vai economizar alguns bytes
Ação do Fundo Monica
2

Perl 6, 101 bytes

Aqui está uma primeira passagem:

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


Usando .transa $_remover 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


Atue @*ARGSdiretamente em vez de definir um MAINsub.
(caso contrário, idêntico ao exemplo anterior)

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

101

Brad Gilbert b2gills
fonte
2

Scala, 111 91 bytes

val f=(_:String).flatMap(x=>if(x.isDigit)('0'to x)else if(x.isUpper)('A'to x)else('a'to x))
Martin Seeler
fonte
Isso falha para pi=3.14159. A solução poderia ter 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)128 caracteres impressionantes?
Leonardo
2

Julia, 102 98 90 84 bytes

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

Isso cria uma função sem nome que aceita uma string e retorna uma string.

Ungolfed:

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.
fonte
2

PowerShell, 155 bytes

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

Tecnicamente uma linha e o PowerShell é tudo sobre isso ;-)

Divide a entrada, canaliza isso em um ForEach-Objectloop, ativa o valor inteiro do caractere convertido e gera novos char[]intervalos apropriados. Observe que precisamos gastar bytes para definir uma variável temp, $bporque o ato de converter a entrada $_na instrução switch significa que não podemos continuar usando$_ ou obteremos uma saída descolada.

EDIT - Devo salientar que isso gerará erros, pois o primeiro objeto sendo alimentado %{...}é um objeto nulo. Como STDERR é ignorado por padrão , isso não deve ser um problema. Se houver algum problema, altere o primeiro bit ($args-split''-ne''|...para eliminar o objeto nulo.

AdmBorkBork
fonte
2

JavaScript (ES6), 340 258 273 271 bytes

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
fonte
Você pode usar uma string de modelo `` for split em vez de ("")e f=i=""no loop for. Você poderá salvar mais alguns bytes.
Intrepidcoder
@intrepidcoder O primeiro funcionaria. Estou verificando o segundo.
Conor O'Brien
2

C (269 bytes)

(quebra de linha adicionada para maior clareza)

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

Ungolfed

#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);
}
musaritmia
fonte
2

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

A combinação de expressões regulares com operadores condicionais funcionou bem nesse caso.
Com uma junção Usando o mapa para combinar os intervalos em uma matriz.

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

Teste

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

Explicação

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

JavaScript (ES7), 125 bytes

Já havia duas respostas JS com foco na codificação das strings, então decidi adotar uma abordagem mais algorítmica usando 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))

Um bônus ao usar esse método é que ele requer qualquer quantidade de códigos de caracteres, portanto, joina lista não é necessária. Acabou sendo mais curto do que qualquer outra técnica, então estou feliz com o resultado.

ETHproductions
fonte
1

MUMPS, 131 bytes

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

Consegui salvar alguns bytes aqui graças ao escopo dinâmico do MUMPS . Aqui está uma versão praticamente não equivalente, que eu gostaria muito de destacar a sintaxe, se apenas o suporte ao módulo MUMPS Prettify estivesse disponível .

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

Perl 6, 78 bytes

@*ARGS[0].trans(/\d/=>{[~] 0..$/},/<:L>/=>{[~] samecase("a",~$/)..~$/}).say
Teclas de atalho
fonte
Eu sabia que poderia ser encurtado combinando os casos 'a'..'z'e 'A'..'Z', eu deveria ter tentado mais.
Brad Gilbert b2gills
Eu recomendo adicionar <!-- language-all: lang-perl6 -->logo após, ## Perl 6para que fique destacado corretamente. (Mudança já está pendente sobre esta resposta)
Brad Gilbert b2gills
Você pode mudar {[~](0..$/)}para o {[~] 0..$/}que salvará um byte.
precisa saber é o seguinte
0

Mathematica, 102 bytes

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

Ah bem...

LegionMammal978
fonte
0

CJam, 32 31 bytes

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

Experimente on-line no intérprete CJam .

Como funciona

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

Python 2, 135 117 bytes

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

PHP - 291 bytes

Passe a string para 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)));
Indefinido
fonte
0

C #, 251 201 184 157 154 154 bytes

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

editar: Greve! Mais curto que o PowerShell;)

Stephan Schinkel
fonte
1
você pode fazer string[]i?
Erik the Outgolfer