Faire une chaîne (quelque peu) auto-référentielle


27

Vous voulez faire une chaîne où le ( 1-indexé caractère) à l' index nest n. Quand nest inférieur à 10, cela est facile: "123456789". Quand nest 12, par exemple, cela devient impossible, car les nombres supérieurs à 9 (en base 10) occupent plus d'un caractère. Nous pouvons transiger en divisant la chaîne en sous - chaînes de deux caractères: "020406081012". Maintenant, l'index de la fin de chaque sous n - chaîne est n.

Cela peut être généralisé pour n'importe dquel nombre à chiffres. Voici une explication de la partie "0991021" de la chaîne pour un nombre à trois chiffres:

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

Si vous ne l'avez pas encore compris, vous devez écrire un programme / fonction qui prend une chaîne ou un entier et produire sa chaîne auto-référentielle comme spécifié ci-dessus. Vous pouvez également générer un tableau de nombres à un chiffre, de caractères ou de chaînes à un seul caractère.

L'entier donné sera toujours positif et divisible par sa longueur (par exemple 126 est divisible par 3; 4928 est divisible par 4). Votre programme devrait théoriquement fonctionner pour une entrée arbitrairement grande, mais vous pouvez supposer qu'il est plus petit que la longueur entière et / ou la chaîne maximale de votre langue.

Quelques observations si vous ne l'obtenez toujours pas: La longueur de la sortie sera toujours l'entrée elle-même, et les nombres qui apparaissent dans la sortie seront divisibles par le nombre de chiffres dans l'entrée.

C'est le , donc la réponse la plus courte en octets l'emporte.

Cas de test

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

Réponses:


8

Gelée , 12 octets

VRUmLDUz0ZFU

Les E / S sont sous forme de tableaux de chiffres. Essayez-le en ligne! ou vérifiez tous les cas de test .

Comment ça marche

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
Écoute, pas d'Unicode!
Dennis

8
Pourtant, il ressemble à un conducteur en colère.
Jonathan Allan

12

C, 64 octets

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

Prend un seul entier comme entrée sur stdin.


9

JavaScript (ES6), 83 octets

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

Oui, c'est une chaîne de modèle imbriquée. 79 octets dans ES7:

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

7

MATL , 15 14 octets

VntG3$:10YA!1e

Essayez-le en ligne!

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 octets

Code:

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

Explication:

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.

La fusion se fait comme ceci:

De ces:

000
 12

Il en résulte:

012

Utilise l' encodage CP-1252 . Essayez-le en ligne! .


Cool! Je ne savais pas que ça ñfonctionnait comme ça.
Emigna

1
@Emigna Oui, mais ça a l'air un peu long. Je devrais probablement faire un builtin pour ce builtin: P.
Adnan

Une fonction intégrée pour le rembourrage serait également très utile.
Emigna

6

Python 2, 78 70 68 64 63 octets

En fait, se baser sur l'idée de la pastèque destructible le rend encore plus petit (l'utilisation inputest encore meilleure) (le remplissage de la chaîne en arrière permet d'économiser 4 octets) (pas ()à while):

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

Voici l'ancienne approche de 70 octets (économiser 8 octets en utilisant des guillemets au lieu de stret en supprimant les crochets autour du générateur grâce à Dennis):

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

J'ai oublié zfill ... zut.
Destructible Lemon

Vous pouvez utiliser à la ​`x`​place de str(x). De plus, vous n'avez pas besoin de []autour du générateur.
Dennis

Vous m'avez encore surpassé ... les moments difficiles nécessitent des mesures sérieuses: je vais devoir passer à python 2
Destructible Lemon

putain, tu l'as encore fait!
Destructible Lemon

1
Vous n'avez pas besoin des parens while(n).
Dennis

5

Python 2, 63 octets

def f(n):l=len(`n`);print'%%0%dd'%l*(n/l)%tuple(range(l,n+1,l))

Testez-le sur Ideone .


3
Chaîne de format de données ° _ °
Karl Napf

4

JavaScript (ES6), 66

Récursif, entrée nsous forme de chaîne (pas un nombre) et limitation de la taille de la chaîne de sortie à 2 Go (ce qui est supérieur à la limite de chaîne de la plupart des moteurs javascript)

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

Tester

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 octets

modifier:

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

première tentative de golf ...


2
Bonjour et bienvenue chez PPCG! Bon premier post!
Rɪᴋᴇʀ

3

2sable , 13 octets

Code:

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

Utilise l' encodage CP-1252 .


pourquoi n'avez-vous pas nommé ce 05AB1F? : 3
Conor O'Brien

1
@ ConorO'Brien J'y ai pensé, mais les noms seraient vraiment similaires et déroutants: p.
Adnan

vous voulez dire15AB1E
ASCII uniquement

3

Brachylog , 53 45 42 37 28 octets

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

Essayez-le en ligne!


3

Bash, 31 22 octets

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

Testez-le sur Ideone .

Merci à @izabera pour avoir joué au golf sur 6 octets!


3

Ruby, 52 48 + ndrapeau = 49 octets

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

Peut-être que vous n'en avez pas besoin chopsi vous supposez que l'entrée est passée sans retour à la ligne? Je ne sais pas si cela fonctionnerait. Ou que diriez-vous de supposer qu'il y en a toujours un et d'écrire l=~-size?
Lynn

@Lynn appeler sizecomme ça ne fonctionne pas pour moi. Eh bien, je me suis souvenu d'une astuce que j'avais utilisée dans une réponse précédente qui est de toute façon plus courte
Value Ink

2

Python 3 2, 79 74 69 65 68 67 octets

Merci Dennis!

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

augmentation du nombre d'octets due à une mauvaise méthode de sortie


1
Ne devrait-il pas être len(x)au lieu de f, puis enregistrer les octets en l'attribuant à une variable?
Karl Napf

Je ne pense pas ... que voulez-vous dire. De plus, je vous aurais surpassé avec python 2, mais des trucs stupides qui se produisent en ce moment ._.
Destructible Lemon

Vous semblez être passé à Python 2. De plus, par consensus sur la méta , l'utilisation du retour arrière pour écraser une partie de la sortie n'est autorisée que dans les défis artistiques ASCII.
Dennis

En Python 2, /effectue des arguments de division entiers foe.integer.
Dennis

2

zsh, 28 octets

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

zsh + seq, 21 20 octets

C'est à peu près la même réponse que Dennis mais en 20 octets parce que zsh

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

2

Haskell, 51 octets

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

2

Perl, 40 octets

Code de 39 octets + 1 pour -n.

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

Usage

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}

Pas vraiment joué du tout, juste une implémentation simple de la spécification.

                        $ / 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 si vous autorisez les arguments de chaîne:

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

Merci à @ user81655!

Non golfé:

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

beaucoup de place pour l'amélioration, mais je suis fatigué en ce moment


Agréable! J'ai trouvé quelques améliorations qui pourraient être apportées (76 octets): n=>eval('c="";for(a=b=(""+n).length;a<=n;a+=b)c+=`${+`1e${b}`+a}`.slice(1)'). Les bits principaux utilisent une forboucle et l' 1e${b}astuce de Neil .
user81655

@ user81655 - ça me donne Uncaught SyntaxError: Invalid or unexpected token. Je n'ai pas encore débogué que je suis éveillé: D
eithed

Hmmm. Il peut s'agir de caractères cachés qui sont parfois ajoutés aux commentaires SO. Essayez de l'écrire.
user81655

2

R, 149 142 138 octets

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="")

Laisser nchardans le code donne un programme avec le même nombre d'octets que de le remplacer b, mais avoir des lettres aléatoires errant dans le code le rend plus ... mystérieux

Non golfé:
chacun nchar(strtoi(something))permet de calculer le nombre de chiffres dans un nombre donné.

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="")

La strsplitfonction génère une liste de vecteurs contenant les éléments séparés. C'est pourquoi vous devez atteindre le premier 1élément de la liste, puis le itroisième élément du vecteur, en écrivantstrsplit[[1]][i]


essayez d'utiliser str_pad ()
hedgedandlevered

@hedgedandlevered: eh bien, cette fonction a besoin d'un package (c'est-à-dire qu'elle ne peut pas être exécutée avec vanilla R), et je ne veux pas l'utiliser pendant PPCG-ing
Frédéric

1

SQF - 164

Utilisation du format de fonction en tant que fichier:

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

Appeler en tant que INTEGER call NAME_OF_COMPILED_FUNCTION


1

PowerShell, 77 octets

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

Utilise l'interpolation de chaînes pour raccourcir les conversions de chaînes. Les parties avant le deuxième point-virgule raccourcissent les noms des objets réutilisés. Ensuite, chaque entier jusqu'à l'entrée - et uniquement ceux qui sont des multiples de la longueur de l'entrée - sont remplis pour être aussi longs que la chaîne d'entrée et finalement joints en un seul.


1

En fait, 30 octets

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

Essayez-le en ligne!

Je ne suis pas satisfait de la longueur de ce code, mais je ne suis pas sûr qu'il puisse être raccourci beaucoup (voire pas du tout).

Explication:

;╝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 octets

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

Essayez-le en ligne . Personne n'a encore posté dans CJam, c'est donc le script que j'ai utilisé pour les cas de test.

Explication

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 octets

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

Les pourboires sont plus que bienvenus. Parvenez à jouer au golf moi-même d'un octet en le changeant d'une boucle for à une boucle while.

Ce code suppose que cela est exécuté à partir de la ligne de commande et que $ argv [1] est l'int.

Grâce à:

@AlexGittemeier Sa suggestion (voir les commentaires) a fait jouer cela de 5 octets à 78 octets.


Vous pouvez changer echo sprintf(...)->printf(...)
Alex Gittemeier

0

Perl 6, 69 59 46 octets

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

1
Vous pouvez utiliser fmtsur la liste au lieu de map, sprintfet [~]. 42 octets
Jo King
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.