Faça uma string (um pouco) auto-referencial


27

Você deseja criar uma cadeia de caracteres onde esteja o caractere ( indexado 1 ) no índice . Quando é inferior a 10, isso é fácil: . Quando 12, por exemplo, torna-se impossível, pois números maiores que 9 (na base 10) ocupam mais de um caractere. Podemos comprometer dividindo a string em substrings de dois caracteres: . Agora, o índice do final de cada substring é .nnn"123456789"n"020406081012" nn

Isso pode ser generalizado para qualquer dnúmero de dígitos. Aqui está uma explicação para a parte "0991021" da sequência de caracteres para um número de três dígitos:

Index:     ... * 97  98  99*100 101 102*103 ...
               *           *           *
               *---+---+---*---+---+---*---+
Character: ... * 0 | 9 | 9 * 1 | 0 | 2 * 1 | ...
               *---+---+---*---+---+---*---+

Se você ainda não descobriu, você deve escrever um programa / função que pega uma string ou um número inteiro e gera sua string autorreferencial, conforme especificado acima. Você também pode gerar uma matriz de números de um dígito, caracteres ou cadeias de caracteres únicos.

O número inteiro sempre será positivo e divisível por seu comprimento (por exemplo, 126 é divisível por 3; 4928 é divisível por 4). Teoricamente, seu programa deve funcionar para uma entrada arbitrariamente grande, mas você pode assumir que é menor que o número inteiro máximo do seu idioma e / ou o comprimento da string.

Algumas observações, se você ainda não entendeu: O comprimento da saída sempre será a própria entrada e os números que aparecerem na saída serão divisíveis pelo número de dígitos na entrada.

Isso é , então a resposta mais curta em bytes vence.

Casos de teste

1    => 1
9    => 123456789
10   => 0204060810
105  => 003006009012015018021024027030033036039042045048051054057060063066069072075078081084087090093096099102105
1004 => 00040008001200160020002400280032003600400044004800520056006000640068007200760080008400880092009601000104010801120116012001240128013201360140014401480152015601600164016801720176018001840188019201960200020402080212021602200224022802320236024002440248025202560260026402680272027602800284028802920296030003040308031203160320032403280332033603400344034803520356036003640368037203760380038403880392039604000404040804120416042004240428043204360440044404480452045604600464046804720476048004840488049204960500050405080512051605200524052805320536054005440548055205560560056405680572057605800584058805920596060006040608061206160620062406280632063606400644064806520656066006640668067206760680068406880692069607000704070807120716072007240728073207360740074407480752075607600764076807720776078007840788079207960800080408080812081608200824082808320836084008440848085208560860086408680872087608800884088808920896090009040908091209160920092409280932093609400944094809520956096009640968097209760980098409880992099610001004

Respostas:


8

Gelatina , 12 bytes

VRUmLDUz0ZFU

A E / S está na forma de matrizes de dígitos. Experimente online! ou verifique todos os casos de teste .

Como funciona

VRUmLDUz0ZFU  Main link. Argument: A (digit array)

V             Eval; turn the digits in A into an integer n.
 R            Range; yield [1, ..., n].
  U           Upend; reverse to yield [n, ..., 1].
    L         Yield the length (l) of A.
   m          Modular; keep every l-th integer in A.
     D        Decimal; convert each kept integer into the array of its digits.
      U       Upend; reverse the digits of each integer.
       z0     Zip/transpose with fill value 0.
         Z    Zip again.
              This right-pads all digit arrays with zeroes.
          F   Flatten the resulting 2D array.
           U  Upend/reverse it.

7
Olha, não, Unicode!
Dennis

8
No entanto, parece um motorista zangado.
Jonathan Allan

12

C, 64 bytes

l,i;main(n){for(scanf("%d%n",&n,&l);i<n;)printf("%0*d",l,i+=l);}

Pega um único inteiro como entrada no stdin.


9

JavaScript (ES6), 83 bytes

n=>[...Array(n/(l=`${n}`.length))].map((_,i)=>`${+`1e${l}`+l*++i}`.slice(1)).join``

Sim, essa é uma sequência de modelos aninhada. 79 bytes no ES7:

n=>[...Array(n/(l=`${n}`.length))].map((_,i)=>`${10**l+l*++i}`.slice(1)).join``

7

MATL , 15 14 bytes

VntG3$:10YA!1e

Experimente online!

V        % Implicitly input number, n. Convert to string
n        % Length of that string, s
t        % Duplicate s
G        % Push n again
3$:      % 3-input range (s,s,n): generates [s, 2*s, ... ] up to <=n
10YA     % Convert each number to base 10. This gives a 2D array of char, with each
         % number on a row, left-padded with zeros if needed
!1e      % Reshape into a string, reading in row-major order. Implicitly display

6

05AB1E , 15 bytes

Código:

LD¹gÖÏvy0¹g×0ñ?

Explicação:

L                # Get the array [1, ..., input].
 D               # Duplicate this array.
  ¹g             # Get the length of the first input.
    Ö            # Check if it's divisible by input length.
     Ï           # Keep those elements.
      vy         # For each...
         ¹g      # Get the length of the first input.
        0  ×     # String multiply that with "0".
            0ñ   # Merge with the number.
              ?  # Pop and print without a newline.

A fusão é feita assim:

A partir destes:

000
 12

Isso resulta em:

012

Usa a codificação CP-1252 . Experimente online! .


Legal! Não sabia que ñfuncionava assim.
Emigna 11/08/16

1
@ Emigna Sim, mas parece um pouco longo. Provavelmente eu deveria criar um builtin para ele: P.
Adnan

Um built-in para preenchimento também seria realmente útil.
Emigna

6

Python 2, 78 70 68 64 63 bytes

Basicamente, basear-se na idéia de melancia destrutível torna-o ainda menor (o uso inputé ainda melhor) (o preenchimento da sequência para trás salva 4 bytes) (não ()em while):

n,s=input(),''
l=len(`n`)
while n:s=`n`.zfill(l)+s;n-=l
print s

Aqui está a antiga abordagem de 70 bytes (economizando 8 bytes usando aspas em vez de stre colocando os colchetes ao redor do gerador, graças a Dennis):

def f(n):l=len(`n`);print"".join(`x`.zfill(l)for x in range(l,n+l,l))

Eu esqueci Zfill ... danado.
Destructible Lemon

Você pode usar em ​`x`​vez de str(x). Além disso, você não precisa []do gerador.
Dennis

Você me derrotou de novo ... tempos difíceis exigem medidas sérias: vou ter que mudar para python 2
Destructible Lemon

droga você fez isso de novo!
Destructible Lemon

1
Você não precisa de parênteses while(n).
Dennis


4

JavaScript (ES6), 66

Recursiva, entrada ncomo uma string (não um número) e limitando o tamanho da string de saída para 2 GB (acima do limite da string da maioria dos mecanismos javascript)

f=(n,i=1e9,s='',l=n.length)=>s[n-1]?s:f(n,i+=l,s+(i+'').slice(-l))

Teste

f=(n,i=1e9,s='',l=n.length)=>s[n-1]?s:f(n,i+=l,s+(i+'').slice(-l))

function test() {
  var v=I.value;
  Alert.textContent=v % v.length ?
    'Warning: input value is not divisible by its string length':'\n';
  Result.textContent=f(v);
}  

test()
<input type=number id=I value=105 oninput='test()' max=500000>
<pre id=Alert></pre>
<pre id=Result></pre>


4

R, 66 64 62 bytes

editar:

x=nchar(n<-scan());paste0(str_pad(1:(n/x)*x,x,,0),collapse="")

primeira tentativa de golfe ...


2
Olá, e bem-vindo ao PPCG! Bom primeiro post!
Rɪᴋᴇʀ

3

2sable , 13 bytes

Código:

g©÷F®N>*0®×0ñ

Usa a codificação CP-1252 .


por que você não nomeou esse 05AB1F? : 3
Conor O'Brien

1
@ ConorO'Brien Na verdade, eu pensei sobre isso, mas os nomes ficariam realmente parecidos e confusos: p.
Adnan

você quer dizer15AB1E
somente ASCII

3

Braquilog , 53 45 42 37 28 bytes

lB,? yN: B% 0, N: ef: {, "0": "9" y:? m.} acAl: Br -: "0" rjb: Acw \ 
lB,? yN: B% 0,10 : B ^: N +: ef: {, "0": "9" y:? M.} Acbw \ 
lB,? YN: B% 0,10: B ^: N +: ef: {: 16 +: @ Prm .} acbw \ lB 
,? yN: B% 0,10: B ^: N +: efbe: 16 +: @ Prmw \
lB,? yN: B% 0,10: B ^: N +: efbew \

Experimente online!


3

Bash, 31 22 bytes

seq -ws '' ${#1}{,} $1

Teste em Ideone .

Obrigado a @izabera por jogar fora 6 bytes!


3

Ruby, 52 48 + nsinalizador = 49 bytes

((l= ~/$/)..$_.to_i).step(l){|j|$><<"%0#{l}d"%j}

Talvez você não precise chopse presumir que a entrada é passada sem uma nova linha à direita? Não tenho certeza se isso funcionaria. Ou que tal supor que sempre exista um e escrever l=~-size?
Lynn

@ Lynn chamando sizeassim não funciona para mim. Bem, lembrei-me de um truque que havia usado em uma resposta anterior que é mais curta de qualquer maneira
Value Ink

2

Python 3 2, 79 74 69 65 68 67 bytes

Graças à dennis!

def f(n):i=l=len(`n`);s='';exec n/l*"s+=`i`.zfill(l);i+=l;";print s

aumento da contagem de bytes devido ao método de saída incorreto


1
Não deveria ser em len(x)vez de fe depois salvar bytes atribuindo-o a uma variável?
Karl Napf

Eu acho que não .. o que você quer dizer? Além disso, eu teria superado você com o python 2, mas algumas coisas estúpidas estão acontecendo agora.
Destructible Lemon

Você parece ter mudado para o Python 2. Além disso, por consenso em meta , o uso de backspace para substituir parte da saída é permitido apenas em desafios de arte ASCII.
Dennis

No Python 2, /realiza argumentos de divisão inteira foe.integer.
Dennis

2

zsh, 28 bytes

printf %0$#1d {$#1..$1..$#1}

zsh + seq, 21 20 bytes

Essa é praticamente a mesma resposta que Dennis, mas em 20 bytes porque o zsh

seq -ws '' $#1{,} $1

2

Haskell, 51 bytes

f n|k<-length$show n=[k,2*k..n]>>=tail.show.(+10^k)

2

Perl, 40 bytes

Código de 39 bytes + 1 para -n.

$}=y///c;printf"%0$}d",$i+=$}while$i<$_

Uso

echo -n 9 | perl -ne '$}=y///c;printf"%0$}d",$i+=$}while$i<$_'
123456789
echo -n 10 | perl -ne '$}=y///c;printf"%0$}d",$i+=$}while$i<$_'
0204060810
echo -n 102 | perl -ne '$}=y///c;printf"%0$}d",$i+=$}while$i<$_'
003006009012015018021024027030033036039042045048051054057060063066069072075078081084087090093096099102
echo -n 1000 | perl -ne '$}=y///c;printf"%0$}d",$i+=$}while$i<$_'
0004000800120016002000240028003200360040004400480052005600600064006800720076008000840088009200960100010401080112011601200124012801320136014001440148015201560160016401680172017601800184018801920196020002040208021202160220022402280232023602400244024802520256026002640268027202760280028402880292029603000304030803120316032003240328033203360340034403480352035603600364036803720376038003840388039203960400040404080412041604200424042804320436044004440448045204560460046404680472047604800484048804920496050005040508051205160520052405280532053605400544054805520556056005640568057205760580058405880592059606000604060806120616062006240628063206360640064406480652065606600664066806720676068006840688069206960700070407080712071607200724072807320736074007440748075207560760076407680772077607800784078807920796080008040808081208160820082408280832083608400844084808520856086008640868087208760880088408880892089609000904090809120916092009240928093209360940094409480952095609600964096809720976098009840988099209961000

2

k4, 27

{,/"0"^(-c)$$c*1+!_x%c:#$x}

Não é realmente um jogo de golfe, apenas uma implementação direta das especificações.

                        $ / string
                       #  / count
                     c:   / assign to c
                   x%     / divide x by
                  _       / floor
                 !        / range (0-based)
               1+         / convert to 1-based
             c*           / multiply by count
            $             / string
       (-c)               / negative count
           $              / pad (negative width -> right-aligned)
   "0"^                   / fill blanks with zeros
 ,/                       / raze (list of string -> string)

2

Javascript - 76

n=>eval('c="";for(a=b=(""+n).length;a<=n;a+=b)c+=`${+`1e${b}`+a}`.slice(1)')

ou 71 se permitir argumentos de sequência:

n=>eval('c="";for(a=b=n.length;a<=n;a+=b)c+=`${+`1e${b}`+a}`.slice(1)')

Graças a @ user81655!

Ungolfed:

function x(n)
{ 
   c = "", a = b = (""+n).length; 
   while(a<=n)
   {
       c=c+"0".repeat(b-(""+a).length)+a
       a+=b;
   }
   return c;
}

muito lugar para melhorias, mas estou cansado agora


Agradável! Eu encontrei algumas melhorias que poderiam ser feitas (76 bytes): n=>eval('c="";for(a=b=(""+n).length;a<=n;a+=b)c+=`${+`1e${b}`+a}`.slice(1)'). Os principais bits estão usando um forloop e o 1e${b}truque de Neil .
User81655

@ user81655 - isso me dá Uncaught SyntaxError: Invalid or unexpected token. Ainda não
depurei

Hummm. Pode ser caracteres ocultos que às vezes são adicionados aos comentários do SO. Tente escrever.
user81655

2

R, 149 142 138 bytes

x=rep(0,n);a=strtoi;b=nchar;for(i in 1:(n=scan()))if(!i%%b(a(n)))x[i:(i-b(a(i))+1)]=strsplit(paste(a(i)),"")[[1]][b(a(i)):1];cat(x,sep="")

Deixar ncharo código fornece um programa com o mesmo número de bytes que o substitui b, mas ter letras aleatórias vagando no código o torna mais ... misterioso

Ungolfed:
Cada um nchar(strtoi(something))permite calcular o número de numerais em um determinado número.

n=scan()   #Takes the integer 
x=rep(0,n) #Creates a vector of the length of this integer, full of zeros

for(i in 1:n)
    if(!i%%b(strtoi(n)))         #Divisibility check
        x[i:(i-nchar(as.integer(i))+1)]=strsplit(paste(a(i)),"")[[1]][nchar(as.integer(i)):1]; 
        #This part replace the zeros from a given position (the index that is divisible) by the numerals of this position, backward.

cat(x,sep="")

A strsplitfunção gera uma lista de vetores contendo os elementos divididos. É por isso que você precisa alcançar o 1elemento st da lista e, em seguida, o ielemento th do vetor, escrevendostrsplit[[1]][i]


tente usar str_pad ()
hedgedandlevered

@hedgedandlevered: bem, esta função precisa de um pacote (ou seja, não pode ser executado com baunilha R), e eu não quero usar tais enquanto PPCG-ing
Frédéric

1

SQF - 164

Usando o formato de função como um arquivo:

#define Q String""
l=(ceil log _this)+1;s='';for[{a=l},{a<=_this},{a=a+l}]do{c=([a]joinQ)splitQ;reverse c;c=(c+['0'])select[0,l];reverse c;s=format[s+'%1',c joinQ]}

Ligar como INTEGER call NAME_OF_COMPILED_FUNCTION


1

PowerShell, 77 bytes

$x="$($args[0])";$l=$x.Length;-join(1..($x/$l)|%{"$($_*$l)".PadLeft($l,'0')})

Usa interpolação de string para encurtar as conversões de string. As partes anteriores ao segundo ponto e vírgula abreviam os nomes das coisas reutilizadas. Então, todo número inteiro até a entrada - e somente aqueles que são múltiplos do comprimento da entrada - é preenchido para ter o comprimento da string de entrada e, finalmente, unidos em uma.


1

Na verdade, 30 bytes

;╝R╛$l;)*@#"%0{}d"f╗`#╜%`MΣ╛@H

Experimente online!

Não estou satisfeito com o comprimento desse código, mas não tenho certeza de que ele possa ser reduzido muito mais (se houver).

Explicação:

;╝R╛$l;)*@#"%0{}d"f╗`#╜%`MΣ╛@H
;╝                              duplicate input, push a copy to reg1
  R                             range(1, input+1)
   ╛$l                          push input from reg1, stringify, length
      ;)                        duplicate and move copy to bottom of stack
        *                       multiply range by length of input
         @#                     swap range with length, make length a 1-element list
           "%0{}d"f             "%0{}d".format(length) (old-style Python format string for zero-padding integers to length of input)
                   ╗            save format string in reg0
                    `#╜%`M      for each value in range:
                     #            make it a 1-element list
                      ╜%          format using the format string
                          Σ     concatenate
                           ╛@H  take only the first (input) characters in the resulting string

0

CJam, 19 bytes

q_,:V\i,%{V+sV0e[}/

Experimente online . Ninguém postou no CJam ainda, então esse é o script que eu usei para os casos de teste.

Explicação

q_,:V  e# Store the length of the input as V
\i,    e# Push the range from 0 to the input
%      e# Keep only every V'th number in the array
{      e# Do this for each number:
  V+   e# Add V to get the right number of leading zeroes
  s    e# Convert to string for left padding
  V    e# Push V, the length to bring each string to, and...
  0    e# The character to add to the left
  e[   e# Left pad
}/

0

PHP, 83 78 bytes

<?$a=$argv[1];$i=$y=strlen($a);while($y<=$a){printf('%0'.$i.'d', $y);$y+=$i;}

Dicas são mais do que bem-vindas. Consiga jogar sozinho um byte, alterando-o de um loop for para um while.

Este código assume que isso está sendo executado a partir da linha de comando e que $ argv [1] é o int.

Graças a:

@AlexGittemeier Sua sugestão (ver comentários) aumentou isso de 5 a 78 bytes.


Você pode mudar echo sprintf(...)->printf(...)
Alex Gittemeier

0

Perl 6, 69 59 46 bytes

{my \a=.chars;(a,2*a...$_).fmt("%0"~a~"s","")}

1
Você pode usar fmtna lista em vez de map, sprintfe [~]. 42 bytes
Jo King
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.