Trier une séquence concaténée


17

Considérons une séquence basée sur les relations de récurrence f(n) = f(n-1)+f(n-2), en commençant par f(1) = x1, f(2) = x2. Pour x1 = 2, x2 = 1, la séquence commence comme ceci:

2  1  3  4  7  11  18  29  47  76  123  199  322  521  843

La concaténation en une chaîne donnera:

213471118294776123199322521843

Maintenant, divisez cette liste en le plus petit nombre possible qui donne y(n) > y(n-1). Commencez par le premier numéro, puis le deuxième, etc. Le premier numéro de sortie doit toujours être un seul chiffre. Remplissez le dernier numéro avec le nombre de zéros requis.

2 13 47 111 829 4776 12319 93225 218430

Vous obtiendrez deux nombres, (x1, x2)en entrée, sur n'importe quel format pratique, et le défi est de sortir la liste triée.

Règles:

  • La fonction et les programmes sont OK
  • La séquence initiale doit comporter exactement 15 chiffres (le dernier est f(15)).
  • x1et x2sont non négatifs (zéro est possible).
  • La sortie peut être dans n'importe quel format pratique
  • Le vecteur de sortie ydoit être créé pour cela y2 > y1.
    • D'abord le plus petit possible y1, puis le plus petit possible y2, y3et ainsi de suite.
  • Si x1 = x2 = 0alors sortez 15 zéros (sur le même format que les autres sorties, c'est-à-dire pas 000000000000000).

Exemples :

Input: 1 1
Output: 1  12  35  81  321  345  589  1442  3337 7610

Input: 3 2
Output: 3  25  71  219  315  0811 3121  23435 55898 145300
                             |
                             Optional leading zero 
Input: 0 0
Output: 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

Le code le plus court en octets gagne. Veuillez inclure un lien vers un interprète en ligne si possible.


Qu'entendez-vous exactement par "les plus petits nombres possibles"? Plus petite moyenne? Le plus petit maximum? Autre chose?
isaacg

@isaacg Donc, comme le nième nombre est supérieur à (n-1) e.
nicael

1
Pour clarifier ma question, quelle serait la bonne division de 5467? 54 67? 5 46 70?
isaacg


3
La chose 0 semble être une exception plutôt ennuyeuse et inutile.
Martin Ender

Réponses:


1

Pyth, 56 octets

LsgM.:sMb2?sQsM.WyHX_1Z`0u?yGX_1GHaGHjkhM.u,eNsN14QYmZ15

Suite de tests

Explication:

Tout d'abord, nous vérifions si l'entrée est précise 0, 0. Si oui, imprimez 15 zéros.

Sinon, nous produisons la séquence, avec jkhM.u,eNsN14Q. Ceci est similaire à l'algorithme Pyth standard pour la séquence de Fibonacci.

Ensuite, nous réduisons cette chaîne. L'accumulateur est une liste de chaînes, représentant chaque nombre dans la séquence divisée. À chaque étape de réduction, nous prenons le caractère suivant et vérifions si l'accumulateur est en ordre, en utilisant la fonction d'assistance y, définie avec LsgM.:sMb2, qui est vraie si l'entrée n'est pas en ordre. S'il est en ordre, nous ajoutons le caractère suivant à la liste comme son propre numéro. Sinon, nous ajoutons le caractère suivant à la fin de la dernière chaîne. Ceci est accompli avec u?yGX_1GHaGH ... Y.

Ensuite, nous effectuons une boucle while fonctionnelle. La boucle continue jusqu'à ce que la liste en cours soit en ordre, en réutilisant la fonction d'assistance. À chaque étape, un 0est ajouté à la fin de la dernière chaîne de la liste. Ceci est accompli avec .WyHX_1Z`0.

Enfin, les chaînes sont converties en entiers, avec sMet imprimées.


Pyth, 51 octets

LsgM.:sMb2?sQsM.WyHX_1Z`0hf!yT_./jkhM.u,eNsN14QmZ15

Je crois que cela fonctionne, mais il est beaucoup trop lent à tester - c'est une solution de force brute pour diviser la chaîne.


Je vais apporter quelques améliorations à la Xfonction, mais le code ci-dessus fonctionne dans la version de Pyth qui était la plus récente lorsque la question a été publiée.


5

JavaScript ES6, 127 135

(a,b)=>eval("for(n=r=[],v=13,o=a+n+b;v--;a=b,b=t)o+=t=b+a;for(d of o+'0'.repeat(99))(n+=d)>+v&&(r.push(v=n),n='');+v?r:[...o]")

Tester

F=(a,b)=>eval("for(n=r=[],v=13,o=a+n+b;v--;a=b,b=t)o+=t=b+a;for(d of o+'0'.repeat(99))(n+=d)>+v&&(r.push(v=n),n='');+v?r:[...o]")

// less golfed

U=(a,b)=>{
  for(n=r=[], o=a+n+b, v=13; v--; a=b, b=t)
    o+= t= b+a;
  for(d of o+'0'.repeat(99))
    if ((n+=d) > +v)
      r.push(v=n), n='';
  return +v ? r : [...o]
}

function test(){
  var i = I.value.match(/\d+/g)
  O.textContent = i.length > 1 ? F(+i[0],+i[1]) : ''
}
test()
A,B : <input id=I value='0 1' oninput='test()'>
<pre id=O></pre>


Il y a une erreur pour x1 = 0, x2> 0, par exemple, entrée "0 1".
flornquake

@flornquake corrigé. Le nombre d'octets reste le même, après avoir réduit un peu le code de remplissage zéro
edc65

2

JavaScript ES6, 187 180 187 184 182 179 175 172 165 160 155 154 octets

(a,b)=>eval('d=""+a+b;for(i=-12,j=1;++i<99;)i<2?(c=b,d+=b=a+b,a=c,r=a?[d[0]]:"0,".repeat(15)):(f=+d.slice(j,i))>r[r.length-1]?(r.push(f),j=++i-1):d+=0;r')

J'obtiens des résultats similaires lorsque je l'exécute 1,1et 3,2teste des cas. 0,0a pris un excès de 26 octets ...

De-golf + converti en ES5 + démo:

function s(a, b) {
  d = "" + a + b;
  for (i = -12, j = 1; ++i < 99;)
    i < 2 ?
      (c = b, d += b = a + b, a = c, r = a ? [d[0]] : "0,".repeat(15))
    : (f = +d.slice(j, i)) > r[r.length - 1] ?
      (r.push(f), j = ++i - 1)
      : d += 0;
  return r
}
document.write(
   s(1,1)+"<br>"+
   s(3,2)+"<br>"+
   s(0,0)
)


Pourquoi produit-il plus de chiffres? Et cela ne devrait-il pas être facile à réparer? L'exigence est n <= 15.
Stewie Griffin

@Stewie Mais bon, le premier produit 12 et le second 11. C'est plus petit que 15.
nicael

La séquence initiale f(n) = f(n-1)+f(n-2)a une valeur maximale d'exactement 15. Le nombre de valeurs de sortie est déterminé sur la base de l'algorithme, rien d'autre.
Stewie Griffin

@Stewie ok, il doit donc être exactement 15, non? Ensuite, par n <= 15, vous voulez dire que les nombres d'entrée sont inférieurs à 15?
nicael

Le nombre de valeurs dans la séquence initiale est de 15. Les valeurs de départ f(1)=x1et f(2)=x2peuvent être supérieures à 15. Le nombre de valeurs de sortie est déterminé sur la base des valeurs d'entrée. Car 3 2ce sera 10.
Stewie Griffin

1

JavaScript (ES6), 162 octets

(a,b)=>(k=[...Array(15).keys(y="")],p=-1,z=k.map(_=>0),a|b?[...k.map(f=n=>n--?n?f(n)+f(n-1):b:a).join``,...z].map(d=>+(y+=d)>p?(p=y,y=" ",p):"").join``:z.join` `)

Explication

(a,b)=>(
  k=[...Array(15).keys(y="")],     // k = array of numbers 0 to 14, initialise y
  p=-1,                            // initialise p to -1 so that 0 is greater than p
  z=k.map(_=>0),                   // z = array of 15 zeroes
  a|b?[                            // if a and b are not 0
      ...k.map                     // for range 0 to 14
      (f=n=>n--?n?f(n)+f(n-1):b:a) // recursive sequence function (0 indexed)
      .join``,                     // join result of f(0) to f(14) as a string
      ...z                         // append zeroes for padding
    ].map(d=>                      // for each digit of concatenated result
      +(y+=d)                      // append the digit to the current number y
      >p?(                         // if the current number is greater than the previous p
        p=y,                       // set previous to the current number
        y=" ",                     // reset y (with space as a separator)
        p                          // output the current number (with space at the start)
      ):""                         // else add nothing to the output
    )
    .join``                        // return the output as a string
  :z.join` `                       // return a bunch of zeroes if a and b are 0
)

Tester


1

Mathematica, 192 octets

f[{0,0}]:=0~Table~15
f@l_:=(t=0;q={};If[#>0,q~Join~{10^⌈Log10[t/#]⌉#},q]&[Last@#]&@FoldList[If[#>t,AppendTo[q,t=#];0,#]&[10#+#2]&,0,Flatten@IntegerDigits@SequenceFoldList[#+#2&,l,Range@13]])

Cas de test:

f[{2, 1}]
(* {2, 13, 47, 111, 829, 4776, 12319, 93225, 218430} *)
f[{3, 2}]
(* {3, 25, 71, 219, 315, 811, 3121, 23435, 55898, 145300} *)
f[{0, 0}]
(* {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} *)

La longueur des noms de fonction me tue.


1

Haskell, 165 159 152 142 141 octets

w=take 15
x#y=x:scanl(+)y(x#y)
0%0=w[0,0..]
x%y=g(-1)(w(x#y)++0%0>>=show)(-1)
g _""_=[]
g b l@(h:t)a|b>a=b:g 0l b|1<2=g(max 0b*10+read[h])t a

Exemple d'utilisation: 3 % 2-> [3,25,71,219,315,811,3121,23435,55898,145300].

Démo en ligne (avec un mainwrapper).

Comment ça fonctionne:

w=take 15
x#y=x:scanl(+)y(x#y)              -- fibonacci sequence generator for x and y

0%0=w[0,0..]                      -- special case 0%0
x%y=g(-1)(w(x#y)++0%0>>=show)(-1) -- calculate fib sequence, add some extra 0 and
                                  -- flatten all digits into a single string.
                                  -- start calculating the resulting sequence

g _""_=[]                         -- if we don't have digits left, stop.
                                  -- the final 0 in the second parameter is ignored.
g b l@(h:t)a
  |b>a=b:g 0l b                   -- if the current number is greater than the
                                  -- previous one, take it and start over.
  |1<2=g(max 0b*10+read[h])t a    -- otherwise add the next digit and retry.
                                  -- The "max" fixes the initial call with -1.

0

PowerShell, 167 166 octets

param($x,$w)if($w-lt($x-eq0)){"0`n"*15;exit}[char[]]("$x"+-join(0..13|%{$w;$w=$x+($x=$w)}))|%{$z+="$_";if(+$z-gt$y){($y=$z);$z=""}};if($z){while(+$z-lt$y){$z+="0"}$z}

Enregistrement d'un octet en éliminant la $svariable et en alimentant directement la boucle de sortie directement.

Non golfé et commenté:

param($x,$w)           # Take input parameters as x and w
if($w-lt($x-eq0)){     # If x=0, ($x-eq0)=1, so $w-lt1 implies w=0 as well
  "0`n"*15             # Print out 15 0's separated by newlines
  exit                 # And exit program
}                      # otherwise ...
[char[]](              # Construct the sequence string as a char-array
"$x"+-join(            # Starting with x and concatenated with a joined array
  0..13|%{             # Loop
    $w                 # Add on w
    $w=$x+($x=$w)      # Recalculate for next loop iteration
  }
))|%{                  # Feed our sequence as a char-array into a loop
  $z+="$_"             # z is our output number, starts with the first digit
  if(+$z-gt$y){        # If z is bigger than y (initialized to 0)
    ($y=$z)            # Set y equal to z and print it
    $z=""              # Reset z to nothing to start building the next number
  }
}
if($z){                # If there is remaining digits, we need to pad zeroes
  while(+$z-lt$y){     # Until z is bigger than y
    $z+="0"            # Tack on a zero
  }
  $z                   # Print the final number
}

0

Perl 6 , 107 octets

{$_=@=(|@_,*+*...*)[^15].join.comb;.sum??[.shift,{last if !@$_;until (my$a~=.shift//0)>$^b {};$a}...*]!!$_} # 107

Usage:

# give it a lexical name for ease of use
my &code = {...}

# use 「eager」 because the anonymous block returns a lazy array
# and 「say」 doesn't ask it to generate the values
say eager code 2, 1;
# [2 13 47 111 829 4776 12319 93225 218430]
say eager code 1, 1;
# [1 12 35 81 321 345 589 1442 3337 7610]
say eager code 3, 2;
# [3 25 71 219 315 0811 3121 23435 55898 145300]
say eager code 0, 0;
# [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
say eager code 0, 1;
# [0 1 12 35 81 321 345 589 1442 3337 7000]

Explication

crée une séquence de type Fibonacci, en commençant par les arguments ( @_) glissé ( |) dans

|@_,*+*...*

prend les 15 premiers éléments de cette séquence

(…)[^15]

combine cela en une seule chaîne ( .join), la divise en une séquence de caractères individuels ( .comb) et la stocke dans le scalaire "par défaut" ( $_) après avoir contraint la séquence dans un tableau mutable, en la stockant d'abord dans un tableau anonyme ( @)

$_=@=(…)[^15].join.comb;

il trouve la somme des valeurs dans le scalaire par défaut, et si c'est zéro retourne le scalaire par défaut, qui contiendra un tableau de 15 zéros

.sum??  !!$_

si la somme n'est pas nulle, elle crée une liste en décalant d'abord le premier élément du scalaire par défaut

.shift,  

suivi de la génération du reste des valeurs, en le comparant à la précédente ( $^b)
si le scalaire par défaut manque de valeurs, utilisez 0 à la place ( //0)

…,{  ;until (my$a~=.shift//0)>$^b {};$a}...*

arrêt lorsqu'il n'y a plus d'éléments dans le scalaire par défaut

…,{last if !@$_;  }...*

pourquoi doit-il y avoir un espace dedans until (my$a...? N'est-ce (pas un délimiteur spécial?
chat

@cat qui serait un appel au sous-programme nommé until, qui n'existe pas.
Brad Gilbert b2gills
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.