确定给定方程为真的基数


22

给定3个整数,请确定前两个整数乘以第三个整数的最低可能基数。如果您想到了关于生命,宇宙和一切终极问题的答案,则6 * 9 == 42在Base 13中是正确的。

输入可以包括任何数字,其数字使用字符0-9,az和AZ,其中以a10为基数等于10,以10为基数等于Z61。

输入应该以您喜欢的任何方式输入(硬编码除外),并且您可以编写单个函数或整个程序。

必须考虑的最大基数是62,最小基数是2。

您可以假定前两个值小于第三个值。您还可以得出结论,最小基数比输入中的最高数字/字符大一个(例如,如果输入为3 1a 55,则最小基数将为Base 11,因为a它是最高数字)。

如果没有这样的基准,则返回您选择的垃圾值。

这是代码高尔夫,所以最短的代码获胜。

测试用例

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

我认为STDIN可能会更好,或者两者都很好。
erdekhayser 2014年

@MartinBüttner那么,我应该只允许使用两种形式的输入吗?
erdekhayser 2014年

1
需要澄清的是,如果多个基准有效,那么该怎么办,例如您的上一个示例(现已删除-10 * 10 = 100),该基准在基准10中也有效,而实际上您关心的任何其他基准提到...
克里斯

1
@Kay如果我以比base 1 b通用的方式a_0 b^0 + a_1 b^1 + a_2 b^2 + ...(其中a_0最低有效数字)以base为单位定义位置系统绝对有意义。此外,OP的结论也将包括在搜索基础1,如果目前最大的数字是0
马丁安德

2
关于基数1,一进制是数字系统。en.m.wikipedia.org/wiki/Unary_numeral_system
erdekhayser 2014年

Answers:


3

CJam,52 51 48字节

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

在这里测试。在线测试仪不支持通过ARGV输入。最接近的替代方法是将输入内容6 9 42放入STDIN中并使用:

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

-1如果找不到最大为62的有效基准,则将打印此消息。

非常感谢Peter提供的数字解析代码!

我修复了很多问题,使计数增加了14个字节。以下说明仍然适用于我的原始提交内容,我将在明天的某个时间进行更新。

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.";

索引会在程序末尾自动打印。


在GS中,数字可以解析为32base~\[-16.35 9]=+。我知道CJam的基本转换时间较短。
彼得·泰勒

7

APL(Dyalog Unicode),30 字节SBCS

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

在线尝试!

感谢Adám的帮助。

说明:

⊢{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

我们使用一个辅助函数,In以更可口的格式接收输入。否则,接收到的输入为3列矩阵。

'3 9 42' 例如:(从上到下,然后从左到右阅读):

0 0 4
3 9 2

并且'aA bB 36jk'(在这里相同。a是10,b是11,A是36,依此类推)

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

2

Python的2 - 197 213

真是个怪物...(与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]

不幸int的是,基数转换最多只能处理36个基数。因此,我需要自己实现。(请参阅此出色的解决方案。)


是否确保不返回小于或等于最大位数的基数?
Martin Ender 2014年

@MartinBüttner:我不确定。至少没有明确。您是否有一个问题的测试用例?(实际上,生成测试用例应由OP负责...)
Falko 2014年

尝试将2 * 3 = 20设置为3(在错误的情况下)。3不是三进制数字系统中的数字。
凯2014年

2

CJam,53个字节

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

接受来自STDIN的三个输入,例如

6 9 42

0如果无法使用任何基础的产品进行打印

将尝试进一步打高尔夫球。

在这里尝试


1

JavaScript(E6)129139

递归尝试2到62之间的所有基数,如果没有值确定,则返回-1。
JavaScript parseInt函数最多可使用36个基数,因此对于较大的基数,需要一点帮助。
注意,参数x,y,z是字符串,而不是数字。
比看起来困难得多。感谢Martin指出第一个版本中的一个基本错误。

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

少打高尔夫球

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

在FireFox / FireBug控制台中测试
该测试尝试使用1000个具有不同基数的数字(最多36个,而不是62个)。值得注意的是,找到的基准可能是正确的,但小于生成测试用例的基准。

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参数是字符串(可能的值类似于aA bB 36jk ...)。在答案中阐明。
edc65

哦,对,这很有意义。
马丁·恩德

1

木炭,28字节

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

在线尝试!链接是详细版本的代码。None如果找不到有效的基数,则输出。说明:

         θ                      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

是否有可能使用您发布的实际代码的TIO程序?
mbomb007

@ mbomb007您可以在线尝试!但是AST生成器似乎认为Any出于某种原因……
尼尔·

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.

添加两个必须出现的前导换行符。

可读性:

#!/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.

调用:

$ 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

是否确保不返回小于或等于最大位数的基数?
Martin Ender

是的,if Digit < Base -> … end零件可以解决这个问题。如果一个if块没有真正的分支,则抛出一个异常,该异常被捕获try … catch _:_ -> … end
凯2014年

0

Haskell 216个字符(177?)

尝试尽可能多地打高尔夫球。如果算入进口,那么这是我最短的代码(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)]

但是,如果不计算进口量,那么这是我最好的版本(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)]

在没有系数大于x的情况下,这会将每个数字视为多项式P(x),其中x是基数。然后,我评估每个可能基数上的多项式,并在达到等式P(x)* Q(x)= R(x)时停止。使用模式匹配中的最后一个后卫强制执行“基数大于最大数字”规则n>(m.map(m.f)$k)。我知道,不同的高尔夫挑战赛和不同的挑战者对于计分的进口都有不同的政策,所以第二个要加盐。


解决方案实际上分别是216177字节/字符。但是第二种解决方案是无效的,因为除非OP明确指定,否则计算导入次数,据我所知,这里不是这种情况。
nyuszika7h 2014年

0

Prolog-195字节

基本上和我的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).

可读性:

:- 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).

调用:

$ 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]))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.