Quante caramelle puoi mangiare?


14

Ringraziamo Geobits in TNB per l'idea

Un post senza dettagli sufficienti ha recentemente proposto un gioco interessante:

2 bambini si siedono davanti a una serie di caramelle. Ogni pezzo di caramella è numerato da 1 a x, con xla quantità totale di caramelle presenti. C'è esattamente 1 occorrenza di ciascun numero.

L'obiettivo del gioco è che i bambini mangino caramelle e moltiplichino i valori delle caramelle che hanno mangiato per arrivare a un punteggio finale, con il punteggio più alto vincente.

Tuttavia, nel post originale sono mancate le informazioni chiave, come il modo in cui vengono selezionate le caramelle, quindi i bambini nella nostra storia hanno deciso che il bambino più grande deve iniziare per primo e possono mangiare fino a metà delle caramelle, tuttavia una volta che annuncia la fine del suo turno, non può cambiare idea.

A uno dei bambini in questo gioco non piacciono le caramelle, quindi vuole mangiare il meno possibile, e una volta ha visto suo padre scrivere un po 'di codice una volta, e figure che può usare le abilità acquisite da quello per capire quante caramelle ha bisogno di mangiare per garantire la vittoria, pur continuando a mangiare il meno possibile.

La sfida

Dato il numero totale di caramelle x, il tuo programma o funzione dovrebbe generare la minima quantità di caramelle che deve mangiare per garantire la vittoria,n , anche se il suo avversario mangia tutte le caramelle rimanenti.

I numeri naturalmente più grandi generano numeri più grandi, quindi qualsiasi importo gli darai, ne mangerà n numeri più grandi.

Le regole

  • xsarà sempre un numero intero positivo nell'intervallo in 0 < x! <= lcui si ltrova il limite superiore delle capacità di gestione dei numeri della tua lingua
  • È garantito che il bambino mangerà sempre il nmaggior numero, ad esempio per x = 5e n = 2, mangerà 4e5

Casi test

x = 1
n = 1
(1 > 0)

x = 2
n = 1
(2 > 1)

x = 4
n = 2
(3 * 4 == 12 > 1 * 2 == 2)

x = 5
n = 2
(4 * 5 == 20 > 1 * 2 * 3 == 6)

x = 100
n = 42
(product([59..100]) > product([1..58]))

x = 500
n = 220
(product([281..500]) > product([1..280]))

punteggio

Sfortunatamente, il nostro coraggioso concorrente non ha nulla con cui scrivere il suo codice, quindi deve disporre le caramelle nei caratteri del codice, di conseguenza, il tuo codice deve essere il più piccolo possibile, il codice più piccolo in byte vince!


14
Quante caramelle posso mangiare? Tutto. Tutte le caramelle.
AdmBorkBork,

3
Nuovo titolo: "Quante caramelle hai bisogno di mangiare?"
Sparr,

@Skidsdev Dovrebbe x = 0essere gestito anche da allora 0! = 1? (Forse xdovrebbe anche essere specificato come numero intero positivo?)
Chronocidal,

@Chronocidal ha aggiunto un numero intero "positivo"
Skidsdev il

Ho gettato 10k pezzi di caramelle per terra. Una piccola figura ha scavato un buco nel terreno e ha trovato una gigantesca caverna di caramelle a causa mia. ):
moonheart08,

Risposte:


9

Python 3 , 76 byte

F=lambda x:x<2or x*F(x-1)
f=lambda x,n=1:x<2or n*(F(x)>F(x-n)**2)or f(x,n+1)

Provalo online!

Si basa sul fatto che per mangiare n caramelle si vince ancora e il numero totale di caramelle è x , x!(xn)!>(xn)!deve essere vero, il che significax!>((xn)!)2.

-1 da Skidsdev

-3 -6 da BMO

-3 da Sparr

+6 da correggere x = 1


1
Puoi salvare 1 byte sostituendo la funzione superiore confrom math import factorial as F
Skidsdev il

1
È possibile riscrivere queste ricorsioni utilizzando comportamenti di cortocircuito, ad es. per la seconda: n*(F(x)>F(x-n)**2)or f(x,n+1). Allo stesso modo x<2or x*F(x-1)per il primo che è più corto dell'importazione.
ბიმო

1
Tutti e tre sono buoni suggerimenti, grazie. (E aggiunto)
nedla2004,

1
-3 byte con i import math;F=math.factorialquali probabilmente dovrei andare a trovare i meta suggerimenti per il pitone da menzionare ...
Sparr

2
@Sparr: Ma F=lambda x:x<2or x*F(x-1)tre byte in meno?
ბიმო

5

JavaScript (ES6), 53 byte

n=>(g=p=>x<n?g(p*++x):q<p&&1+g(p/n,q*=n--))(q=x=1)||n

Provalo online!

Campo di lavoro

È interessante notare che le differenze tra i prodotti per bambini sono sempre abbastanza grandi che la perdita di precisione inerente alla codifica IEEE 754 non è un problema.

Di conseguenza, funziona per 0n170 . Oltre a ciò, sia la mantissa che l' espansore traboccano (cedendo + Infinito ) e avremmo bisogno di BigInts (+1 byte).

Come?

Lascia che p sia il prodotto di caramelle dell'altro bambino e che q sia il nostro prodotto di caramelle.

  1. Iniziamo con p=n!(tutte le caramelle per l'altro bambino) e q=1 (niente per noi).

  2. Ripetiamo le seguenti operazioni fino a qp :

    • dividere p per n
    • moltiplicare q per n
    • decremento n

Il risultato è il numero di iterazioni richieste. (Ad ogni iterazione, "prendiamo la caramella successiva più alta dall'altro bambino".)

Commentate

Questo è implementato come una singola funzione ricorsiva che prima calcola n!e quindi entra nel loop sopra descritto.

n => (           // main function taking n
  g = p =>       // g = recursive function taking p
    x < n ?      //   if x is less than n:
      g(         //     this is the first part of the recursion:
        p * ++x  //     we're computing p = n! by multiplying p
      )          //     by x = 1 .. n
    :            //   else (second part):
      q < p &&   //     while q is less than p:
      1 + g(     //       add 1 to the final result
        p / n,   //       divide p by n
        q *= n-- //       multiply q by n; decrement n
      )          //
)(q = x = 1)     // initial call to g with p = q = x = 1
|| n             // edge cases: return n for n < 2

4

Gelatina , 9 byte

ḊPÐƤ<!€TL

Provalo online! Oppure vedi la suite di test .

Come?

ḊPÐƤ<!€TL - Link: integer, x                   e.g. 7
Ḋ         - dequeue (implicit range of x)           [   2,   3,   4,   5,   6,   7]
  ÐƤ      - for postfixes [all, allButFirst, ...]:
 P        -   product                               [5040,2520, 840, 210,  42,   7]
      €   - for each (in implicit range of x):
     !    -   factorial                             [   1,   2,   6,  24, 120, 720, 5040]
    <     - (left) less than (right)?               [   0,   0,   0,   0,   1,   1, 5040]
          -   -- note right always 1 longer than left giving trailing x! like the 5040 ^
       T  - truthy indices                          [                       5,   6, 7   ]
        L - length                                  3

1
è impressionante ma sarebbe più
istruttivo

Sarà ... :)
Jonathan Allan il

@Setop - aggiunto.
Jonathan Allan,

mi piace ! e deve essere veloce rispetto a tutte le soluzioni con tonnellate di fattoriali
Setop

No, calcola ancora tutti quei prodotti e fattoriali (più di alcune altre soluzioni).
Jonathan Allan,

3

R , 70 41 38 byte

-29 perché Dennis conosce tutte le funzioni interne

-3 passaggio all'ingresso scan ()

sum(prod(x<-scan():1)<=cumprod(1:x)^2)

Provalo online!

Implementazione R piuttosto semplice della risposta Python3 di nedla2004 .

Sento che esiste un'implementazione più pulita della gestione 1 e vorrei perdere le parentesi graffe.

Sono pazzo, non sono tornato a usare un approccio del genere, più folle che ho usato un rigoroso meno di, ma ancora più folle che non sapevo che ci fosse una cumprod()funzione. Grande ottimizzazione di Dennis.


3

APL (Dyalog Unicode) , 10 byte

+/!≤2*⍨!∘⍳

Provalo online!

La risposta di Port of Dennis . Grazie a Dennis per questo.

Come:

+/!≤2*⍨!∘⍳  Tacit function, takes 1 argument (E.g. 5)
           Range 1 2 3 4 5
       !∘   Factorials. Yields 1 2 6 24 120
    2*⍨     Squared. Yields 1 4 36 576 14400
  !         Factorial of the argument. Yields 120.
           Less than or equal to. Yields 0 0 0 1 1
+/          Sum the results, yielding 2.

Dal momento che questa risposta non è stata fatta da me rigorosamente, terrò la mia risposta originale di seguito.


APL (Dyalog Unicode) , 14 12 11 byte

(+/!>×\)⌽∘⍳

Provalo online!

Prefisso funzione tacita. Fondamentalmente un porto dyalog della risposta di Jonathan .

Grazie a ngn e H.PWiz per l'aiuto nella chat. Grazie a ngn anche per avermi salvato un byte.

Grazie a Dennis per aver sottolineato che il mio codice originale era sbagliato. Si scopre che mi ha salvato 2 byte.

Usi ⎕IO←0.

Come:

+/(!>×\)∘⌽∘⍳  Tacit function, taking 1 argument (E.g. 5).
             Range 0 1 2 3 4
         ⌽∘   Then reverse, yielding 4 3 2 1 0
  (    )∘     Compose with (or: "use as argument for")
   !          Factorial (of each element in the vector), yielding 24 6 2 1 1
     ×\       Multiply scan. Yields 4 12 24 24 0
    >         Is greater than. Yields 1 0 0 0 1
+/            Finally, sum the result, yielding 2.

1
se +/si trova tra parentesi, si può omettere una delle composizioni:(+/!>×\)⌽∘⍳
ngn

2

Haskell , 52 51 byte

nX!(X-n)!n(X-n)!n

g b=product[1..b]
f x=[n|n<-[1..],g(x-n)^2<=g x]!!0

Provalo online!


2

Gelatina , 7 byte

R!²<!ċ0

Provalo online!

Come funziona

R!²<!ċ0  Main link. Argument: n

R        Range; yield [1, ..., n].
 !       Map factorial over the range.
  ²      Take the squares of the factorials.
    !    Compute the factorial of n.
   <     Compare the squares with the factorial of n.
     ċ0  Count the number of zeroes.

2

Python 3 , 183 176 149 byte

R=reversed
def M(I,r=1):
 for i in I:r*=i;yield r
def f(x):S=[*range(1,x+1)];return([n for n,a,b in zip([0]+S,R([*M(S)]),[0,*M(R(S))])if b>a]+[x])[0]

Provalo online!

È molto più veloce di altre soluzioni - moltiplicazioni 0 (N) anziché O (N²) - ma non riesco a ridurre la dimensione del codice.

-27 da Jo King



1

05AB1E , 15 11 byte

E!IN-!n›iNq

Provalo online!

E!IN-!n›iNq

E                For loop with N from [1 ... input]
 !               Push factorial of input    
  IN-            Push input - N (x - n)
     !           Factorial
      n          Square
       ›         Push input! > (input - N)^2 or x! > (x - n)^2
        i        If, run code after if top of stack is 1 (found minimum number of candies)
         N       Push N
          q      Quit, and as nothing has been printed, N is implicitly printed

Utilizza lo stesso approccio del mio Python presentazione . Nuovo di 05AB1E, quindi tutti i suggerimenti sul codice o sulla spiegazione sono molto apprezzati.

-4 byte grazie a Kevin Cruijssen


Bella risposta! Puoi giocare a golf a 3 byte in questo modo senza interrompere l'input 1. Se l'istruzione if è vera, spingerà l'indice Nnello stack e uscirà dal programma (producendo implicitamente quell'indice). Per input 1l'istruzione if sarà falsa, ma produrrà il suo input 1implicitamente dopo quel ciclo a iterazione singola.
Kevin Cruijssen,

1
In realtà, è possibile salvare 4 byte anziché 3: provalo online 11 byte . L'input verrà usato implicitamente per il primo fattoriale !, ora che lo stack è vuoto poiché non dupliciamo / tripliciamo più il if-risultato.
Kevin Cruijssen,

1
Grazie per queste idee Anche se alla fine non ho avuto l'idea di stampare, ho pensato di terminare anticipatamente il ciclo for. Dopo aver cercato pausa, fine, uscita e fuga, pensavo solo di non capire il modo in cui i loop funzionano correttamente. In qualche modo terminare non mi è mai successo.
nedla2004,

1
La tua risposta era già abbastanza buona. Di solito è più facile giocare a golf una risposta esistente, quindi giocare a golf da soli. Se avessi fatto questa sfida da solo, probabilmente sarei finito anche a 15 o 14 byte. Ho usato la tua idea di interrompere e sostituirlo con un output terminato e implicito, dopo di che ho provato alcune cose, e alla fine ho visto che non avevo più bisogno del duplicato, il che avrebbe anche risolto il caso di test 1producendo l'input implicitamente quando lo stack è vuoto. :)
Kevin Cruijssen il

1
Cordiali saluti: Ho pubblicato un'alternativa di 7 byte eseguendo il porting di Dennis ♦ 'Jelly answer. Come sempre, Dennis ♦ è in grado di eseguire magie in termini di Jelly code-golf ..; p
Kevin Cruijssen,


0

Carbone , 20 byte

NθI⊕ΣEθ‹Π⊕…ιθ∨Π…¹⊕ι¹

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

Nθ                      Input `n`
    Σ                   Sum of
      θ                 `n`
     E                  Mapped over implicit range
        Π               Product of
           ι            Current value
          …             Range to
            θ           `n`
         ⊕              Incremented
       ‹                Less than
              Π         Product of
                ¹       Literal 1
               …        Range to
                  ι     Current value
                 ⊕      Incremented
             ∨          Logical Or
                   ¹    Literal 1
   ⊕                    Incremented
  I                     Cast to string
                        Implicitly print

Productsu un elenco vuoto in Carbone restituisce Nonepiuttosto che 1, quindi devo logicamente Or.


Sei sicuro che questi personaggi siano 8 bit ciascuno?
RosLuP,

@RosLuP Charcoal è una delle molte lingue che potresti trovare qui che utilizza una tabella codici personalizzata anziché, diciamo, ASCII. Ciò significa che ogni valore a otto bit è associato a un simbolo personalizzato; questi simboli sono progettati per aiutare il programmatore a ricordare ciò che ogni byte fa un po 'più facilmente che se fossero semplicemente casualmente dispersi in una delle pagine di codice standardizzate. Sentiti libero di chiedere maggiori dettagli nella chat di PPCG .
Phlarx,

0

PHP , 107 byte

<?php $x=fgets(STDIN);function f($i){return $i==0?:$i*f($i-1);}$n=1;while(f($x)<f($x-$n)**2){$n++;}echo $n;

Provalo online!

Usa lo stesso X2>((X-1)!)2 metodo come altri hanno usato.

Utilizza la funzione fattoriale dalla presentazione PHP per questa sfida (grazie a @ donutdan4114)



0

05AB1E , 7 byte

L!ns!@O

Port of Dennis ♦ 'Jelly risponde , quindi assicurati di votarlo se ti piace questa risposta!

Provalo online o verifica tutti i casi di test .

Spiegazione:

L          # List in the range [1, (implicit) input]
 !         # Take the factorial of each
  n        # Then square each
   s!      # Take the factorial of the input
     @     # Check for each value in the list if they are larger than or equal to the
           # input-faculty (1 if truthy; 0 if falsey)
      O    # Sum, so determine the amount of truthy checks (and output implicitly)

0

Japt -x, 7 byte

Soluzione Jelly del porto di Dennis.

Funziona solo nella pratica fino a n=4quando non entriamo nella notazione scientifica sopra quella.

õÊ®²¨U²

Provalo

õ           :Range [1,input]
 Ê          :Factorial of each
  ®         :Map
   ²        :  Square
    ¨       :  Greater than or equal to
     U²     :  Input squared
            :Implicitly reduce by addition


0

C (gcc) , 68 byte

n;f(x){int i=2,j=x,b=1,g=x;while(i<j)b*i>g?g*=--j:(b*=i++);n=x-j+1;}

Provalo online!

Modifica: scambia byte con mults, non fare 2 * x mults invece di x + n

Modifica: torna a int anziché a lungo attraverso la macro. Fallirebbe a 34 a lungo.

Bene, ho questo in C. Fails at 21.

C'è una possibile ambiguità sul fatto che il bravo ragazzo voglia sempre vincere o non perdere mai ... che ne pensi?


In genere non permettiamo che il modo in cui hai definito T sia di alcun tipo. Puoi ottenere 72 byte rimuovendo tutti i riferimenti a T, ma devi inoltrare ancora i / j / b / g. Provalo online!
LambdaBeta,

OK ho rimesso la versione con int, che è ancora 68 byte. Quindi non stavo davvero tradendo;)
Balzola il

Lascerei la versione T e un'alternativa. È interessante provare tipi più grandi / più piccoli. Buona presentazione però!
LambdaBeta,

0

Python 3 , 75 byte

f=lambda n:n<1or f(n-1)*n
n=lambda x:x-sum(f(n)**2<f(x)for n in range(1,x))

Provalo online!

Versione 74 byte

f=lambda n:n<1or f(n-1)*n
n=lambda x:1+sum(f(n)>f(x)**.5for n in range(x))

ma questa versione ha traboccato per 500 ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.