Determina la base in cui una determinata equazione è vera


22

Dati 3 numeri interi, determinare la base più bassa possibile per i primi due numeri interi da moltiplicare nel terzo. Se pensi alla Risposta alla Ultima Domanda di Vita, L'Universo e Tutto, 6 * 9 == 42, è vero nella Base 13.

Gli input possono includere qualsiasi numero le cui cifre usano i caratteri 0-9, az e AZ, dove è auguale a 10 nella Base 10 e Zè 61 nella Base 10.

Gli input devono essere immessi nel modo che preferisci (tranne che per l'hard-coding) e puoi scrivere una singola funzione o un intero programma.

La base massima che deve essere considerata è la Base 62 e la base minima è la Base 2.

Puoi presumere che i primi due valori siano più piccoli del terzo. Puoi anche concludere che la base minima è una maggiore della cifra / carattere più alta dagli input (ad esempio, se gli input sono 3 1a 55, la base minima sarebbe Base 11, perché aè la cifra più alta).

Se non esiste tale base, restituisci un valore indesiderato a tua scelta.

Questo è il codice golf, quindi vince il codice più corto.

Casi test

6 9 42     -->   13
a a 64     -->   16
aA bB 36jk -->   41
2 3 20     -->   <junk value>
10 10 100  -->   2

Penso che STDIN sarebbe probabilmente migliore, e andrebbe bene lo stesso.
Erdekhayser,

@ MartinBüttner Quindi dovrei solo consentire l'input in entrambe le forme?
Erdekhayser,

1
A titolo di chiarimento cosa si dovrebbe fare se più basi sono valide come il tuo ultimo esempio (che è stato rimosso - era 10 * 10 = 100) dove è valido anche nella base 10 e in effetti qualsiasi altra base a cui tieni menzione ...
Chris,

1
@Kay Se definisco il sistema posizionale in base bin modo generale come a_0 b^0 + a_1 b^1 + a_2 b^2 + ...(dove a_0è la cifra meno significativa) di base 1 ha sicuramente senso. Inoltre, la conclusione del PO includerebbe anche la base 1 nella ricerca se la cifra attuale più grande è 0.
Martin Ender,

2
Circa la base 1, unario è un sistema numerico. en.m.wikipedia.org/wiki/Unary_numeral_system
erdekhayser

Risposte:


3

CJam, 52 51 48 byte

63,{_ea{i32b~\([G-35-9]=-_Xe>:X;}f%fbW%~*=\X>*}#

Provalo qui. Il tester online non supporta l'input tramite ARGV. L'alternativa più vicina è mettere l'input come 6 9 42in STDIN e usare:

lS/:E;
63,{_E{i32b~\([G-35-9]=-_Xe>:X;}f%fbW%~*=\X>*}#

Stampa -1se non è possibile trovare una base valida fino a 62.

Mille grazie a Peter per il codice di analisi delle cifre!

Ho risolto molti problemi che hanno aggiunto 14 byte al conteggio. La seguente spiegazione è ancora per la mia presentazione originale e la aggiornerò domani.

63,{_ea{i32b~\([G-35-9]=-_Xe>:X;}f%fbW%~*=\X>*}#
63,                                              "Push the array [0 1 .. 62].";
   {                                          }# "Find the first index for which the block returns
                                                  a truthy value.";
    _                                            "Duplicate the current base.";
     ea                                          "Read ARGV into an array of strings.";
       {                        }f%              "Apply this block to each character.";
        i32b                                     "Convert to code point, and then to base-32. The
                                                  most significant digit now identifies the 'type'
                                                  of digit.";
            ~\(                                  "Unwrap the array. Swap the digits. Decrement.";
               [G-35-9]                          "Push array [16 -35 -9] of digit offsets.";
                       =-                        "Select the relevant offset and subtract it from 
                                                  the least significant digit.";
                         _                       "Duplicate the current digit D.";
                          Xe>:X;                 "X := max(X,D). X is predefined as 1.";
                                   fb            "Convert all numbers to the current base.";
                                     W%          "Reverse the list of numbers.";
                                       ~         "Unwrap the array.";
                                        *=       "Multiply factors. Check equality with product.";
                                          \      "Swap result with current base.";
                                           X>    "Ensure base is greater than X.";
                                             *   "Multiply boolean results.";

L'indice viene stampato automaticamente alla fine del programma.


In GS le cifre possono essere analizzate come 32base~\[-16.35 9]=+. So che CJam ha una conversione base più breve.
Peter Taylor,

7

APL (Dyalog Unicode) , 30 byte SBCS

⊢{3e=×/2e←⍵⊥⍺:⍵⋄⍺∇⍵+1}1+⌈/∘,

Provalo online!

Grazie ad Adám per l'aiuto.

Spiegazione:

⊢{3e=×/2e←⍵⊥⍺:⍵⋄⍺∇⍵+1}1+⌈/∘,  
                               left argument ⍺: the vector (do nothing)
                        1+⌈/∘,  right argument ⍵: our starting base.
                             ,              start by flattening the matrix of arguments                               ⌈/                reduce by max (find the highest number)
                                           compose both of these together
                        1+                  increment by one
 {         ⍵⊥⍺         }        convert inputs to the current base
 {       e            }        store the converted values in 3
 {      2             }        take the first 2 values
 {    ×/               }        multiply them together (reduce-multiply)
 {  e=                 }        compare with e (the converted inputs)
 {3                   }        only keep the result of the comparison with the 3rd element (expected result)
 {             :⍵      }        if truthy, return the current base.
 {                    }        otherwise...
 {                ⍺∇⍵+1}        ...recurse with the base incremented

Usiamo una funzione di aiuto In, per ricevere l'input in un formato più gradevole. In caso contrario, l'ingresso riceve una matrice di 3 colonne.

'3 9 42' darebbe, ad esempio (leggi dall'alto verso il basso quindi da sinistra a destra):

0 0 4
3 9 2

E per 'aA bB 36jk'(lo stesso qui. aÈ 10, bè 11, Aè 36, ecc.)

 0  0  3
 0  0  6
10 11 19
36 37 20

2

Python 2 - 197 213

Che mostro ... (rispetto a CJam)

from string import*
I=raw_input()
x,y,z=I.split()
B=lambda s,b:sum(b**i*(digits+lowercase+uppercase).find(s[-i-1])for i in range(len(s)))
print([b for b in range(B(max(I),10)+1,62)if B(x,b)*B(y,b)==B(z,b)]+[0])[0]

Sfortunatamente intla conversione di base può gestire solo basi fino a 36. Quindi ho dovuto implementarlo da solo. (Vedi questa meravigliosa soluzione .)


Questo assicura che non restituisca una base inferiore o uguale alle cifre più grandi?
Martin Ender,

@ MartinBüttner: non ne sono sicuro. Almeno non esplicitamente. Hai un caso di prova in cui questo è un problema? (In realtà, la generazione di casi di test dovrebbe essere curata dall'OP ...)
Falko,

Prova 2 * 3 = 20 che ha la base 3 in un caso di errore. 3 non è una cifra in un sistema numerico ternario.
Kay,

2

CJam, 53 byte

lA,s'{,97>+'[,65>+f#_$W=1e>)63,>_@Wa/W%f{fb~*=}1#\0+=

Prende i tre input da STDIN come

6 9 42

Stampa 0se il prodotto in una base non è possibile

Proverò a golf ulteriormente.

Provalo qui


1

JavaScript (E6) 129 139

Prova in modo ricorsivo tutte le basi da 2 a 62, restituendo -1 se nessun valore è ok.
La funzione JavaScript parseInt funziona con una base fino a 36, ​​quindi è necessario un piccolo aiuto per basi più grandi.
Attenzione, i parametri x, y, z sono stringhe, non numeri.
È più difficile di quanto sembri. Grazie a Martin per aver segnalato un bug di base nella prima versione.

F=(x,y,z,b=2,N=n=>[for(d of(t=0,n))t=(v=parseInt(d,36)+(d>'@'&d<'a')*26)<b?t*b+v:NaN]&&t)=>b<63?N(x)*N(y)!=N(z)?F(x,y,z,b+1):b:-1

Meno golf

F=(x,y,z,b=2,
   D=d=>parseInt(d,36)+(d>'@'&d<'a')*26, // parse a single digit
   N=n=>[for(d of(t=0,n))t=(v=D(d))<b?t*b+v:NaN]&&t // parse a string
)=>b<63?N(x)*N(y)!=N(z)?F(x,y,z,b+1):b:-1

Test nella console FireFox / FireBug.
Il test prova 1000 numeri con basi diverse (fino a 36, ​​non 62). Vale la pena notare che la base trovata potrebbe essere corretta ma inferiore alla base che ha generato il test case.

for(i=0;i<1000;i++)
{
   x=Math.random()*100|0,y=Math.random()*100|0,z=x*y,b=Math.random()*35+2|0
   bx=x.toString(b),by=y.toString(b),bz=z.toString(b),
   nb=F(bx,by,bz)
   nx=parseInt(bx,nb),ny=parseInt(by,nb),nz=parseInt(bz,nb)
   // if (nx*ny != nz) // uncomment to se output for errors only
     console.log(x,y,z,'base '+b,bx,by,bz, 'found base '+nb,nx,ny,nz,nx*ny)
}

@ MartinBüttner i parametri sono stringhe (poiché i valori possibili sono qualcosa come aA bB 36jk ...). Chiarito nella risposta.
edc65,

Oh giusto, ha senso.
Martin Ender,

1

Carbone , 28 byte

I⌊Φ…⊕⍘⌈⁺⁺θηζ⁶²¦⁶³⁼×⍘θι⍘ηι⍘ζι

Provalo online! Il collegamento è alla versione dettagliata del codice. Emette Nonese non è possibile trovare una base valida. Spiegazione:

         θ                      First input
        ⁺                       Concatenated with
          η                     Second input
       ⁺                        Concatenated with
           ζ                    Third input
      ⌈                         Maximum character (by ordinal)
     ⍘                          Converted from base
            ⁶²                  Literal 62
    ⊕                           Incremented
   …                            Range up to
               ⁶³               Literal 63
  Φ                             Filtered by
                    θ           First input
                   ⍘            Converted from base
                     ι          Current value
                  ×             Multiplied by
                       η        Second input
                      ⍘         Converted from base
                        ι       Current value
                 ⁼              Equals
                          ζ     Third input
                         ⍘      Converted from base
                           ι    Current value
 ⌊                              Minimum
I                               Cast to string
                                Implicitly print

È possibile avere un programma TIO che utilizza il codice effettivo che hai pubblicato?
mbomb007,

@ mbomb007 Puoi provarlo online! ma il generatore AST sembra pensare che sia Anyper qualche motivo ...
Neil

0

Erlang (escript) - 200

main(X)->m(2,X).
m(63,_)->0;m(C,X)->try[F,G,I]=[c(0,C,Y)||Y<-X],I=F*G,io:fwrite("~p",[C])catch _:_->m(C+1,X)end.
c(A,B,[H|T])->D=H-if$A>H->$0;$a>H->29;0<1->87end,if D<B->c(A*B+D,B,T)end;c(A,_,_)->A.

Aggiungi due nuove linee principali che devono essere presenti.

Leggibile:

#!/usr/bin/env escript

main(Args) -> test(2, Args).

test(63, _) -> 0;
test(Base, Args) ->
    try
        [Factor1, Factor2, Product] = [convert(0, Base, Arg) || Arg <- Args],
        Product = Factor1 * Factor2,
        io:fwrite("~p", [Base])
    catch _:_ ->
        test(Base + 1, Args)
    end.

convert(Accumulator, Base, [Head|Tail]) ->
    Digit = Head - if Head < $A -> $0;
                      Head < $a -> $A - 10 - 26;
                      true      -> $a - 10
                   end,
    if Digit < Base ->
        convert(Accumulator * Base + Digit, Base, Tail)
    end;
convert(Accumulator, _, _) -> Accumulator.

Invocazione:

$ escript x.erl 6 9 42
13
$ escript -i x.erl a a 64
16
$ escript -i x.erl aA bB 36jk
41
$ escript -i x.erl 2 3 20
(no output)
$ escript -i x.erl 10 10 100
2

Questo assicura che non restituisca una base inferiore o uguale alle cifre più grandi?
Martin Ender,

Sì, la if Digit < Base -> … endparte se ne occupa. Se un ifblocco non ha un vero ramo, viene generata un'eccezione, che viene catturata try … catch _:_ -> … end.
kay,

0

Haskell 216 char (177?)

Ho cercato di giocare a golf il più possibile. Se vengono conteggiate le importazioni, questo è il mio codice più breve (216)

import Data.Char
import Data.List
m=maximum
j[]=0;j(x:_)=x
f=reverse.map(\x->ord x-48)
g[]_=0;g(m:n)x=m+x*g n x
main=do
l<-getLine
let k@[x,y,z]=words l
print$j[n|n<-[2..62],g(f x)n*g(f y)n==g(f z)n,n>(m.map(m.f)$k)]

Tuttavia, se le importazioni non sono state conteggiate, questa è la mia versione migliore (177):

import Data.Char
import Data.List
import Control.Applicative
m=maximum
j[]=0;j(x:_)=x
f=reverse.map(\x->ord x-48)
g[]_=0;g(m:n)x=m+x*g n x
main=words<$>getLine>>= \k@[x,y,z]->print$j[n|n<-[2..62],g(f x)n*g(f y)n==g(f z)n,n>(m.map(m.f)$k)]

Questo considera ogni numero come un polinomio P (x) dove x è la base, a condizione che nessun coefficiente sia maggiore di x; Quindi valuto i polinomi su ogni possibile base, fermandomi quando ne raggiungo uno che soddisfa l'uguaglianza P (x) * Q (x) = R (x). La regola 'base è più grande della cifra più grande' viene applicata con l'ultima guardia nella corrispondenza del modello, vale a dire n>(m.map(m.f)$k). So che le diverse sfide del golf e i diversi creatori di sfide hanno politiche diverse per quanto riguarda le importazioni rispetto al punteggio, quindi prendi la seconda con un granello di sale.


Le soluzioni sono in realtà 216 e 177 byte / caratteri, rispettivamente. Ma la seconda soluzione non è valida, poiché le importazioni vengono conteggiate a meno che il PO non specifichi diversamente, il che non è il caso qui per quanto posso dire.
nyuszika7h,

0

Prolog - 195 byte

Fondamentalmente la stessa idea della mia risposta Erlang:

:-use_module(library(main)).
main(A):-between(2,62,B),maplist(x(B),A,[F,G,P]),0is F*G-P,write(B).
c(I,B,Q,O):-Q=[H|T]->(H<65->D=48;H<97->D=29;D=87),H-D<B,c(I*B+H-D,B,T,O);O=I.
c(B)-->name,c(0,B).

Leggibile:

:- use_module(library(main)).

main(Args) :-
    between(2, 62, Base),
    maplist(convert(Base), Args, [Factor1, Factor2, Product]),
    0 is Factor1 * Factor2 - Product,
    write(Base).

convert(Accumulator, Base, List, Output) :-
    List = [Head|Tail] ->
        (   Head < 65 -> Offset = 48;
            Head < 97 -> Offset = 29;
                         Offset = 87),
        Head - Offset < Base,
        convert(Accumulator * Base + Head - Offset, Base, Tail, Output);
    Output = Accumulator.

convert(Base, Input, Output) :-
    name(Input, List),
    convert(0, Base, List, Output).

Invocazione:

$ swipl -qg main x.pl 6 9 42
13
$ swipl -qg main x.pl aA bB 36jk
41
$ swipl -qg main x.pl 2 3 20
ERROR: Unknown message: goal_failed(main([2,3,20]))
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.