挑战
这是一个简单的例子。
当以10为底的数字作为输入时,编写一个函数或程序,它将以十六进制返回或打印该数字的值。
例子
15 -> F
1000 -> 3E8
256 -> 100
规则
- 没有内置的十六进制功能
- 字母可以小写或大写
- 您只需要担心非负整数,无负数或讨厌的小数
- 它应该可以处理任意数量的数字,直到语言的默认类型限制。
- 换行不是必需的
- 像往常一样,这是代码高尔夫球,因此以字节为单位的最短代码胜出!
000003E8
?
这是一个简单的例子。
当以10为底的数字作为输入时,编写一个函数或程序,它将以十六进制返回或打印该数字的值。
15 -> F
1000 -> 3E8
256 -> 100
000003E8
?
Answers:
必须与一起运行⎕IO←0
,这在许多APL系统上是默认设置。
(⎕D,⎕A)[16⊥⍣¯1⊢⎕]
(⎕D,⎕A)[
... ]
d连接起来以igits 一个 lphabet,然后通过索引...
16⊥⍣¯1
16到数字的逆,即16到数字
⊢
应用于
⎕
数字输入
和往常一样,我使用此处定义的规则表语法。您可以在该站点上进行测试,也可以使用此java实现。
0 * * l B
B * * l C
C * 0 r D
D * * r E
E * * r A
A _ * l 1
A * * r *
1 0 9 l 1
1 1 0 l 2
1 2 1 l 2
1 3 2 l 2
1 4 3 l 2
1 5 4 l 2
1 6 5 l 2
1 7 6 l 2
1 8 7 l 2
1 9 8 l 2
1 _ * r Y
Y * * * X
X * _ r X
X _ _ * halt
2 * * l 2
2 _ _ l 3
3 * 1 r 4
3 1 2 r 4
3 2 3 r 4
3 3 4 r 4
3 4 5 r 4
3 5 6 r 4
3 6 7 r 4
3 7 8 r 4
3 8 9 r 4
3 9 A r 4
3 A B r 4
3 B C r 4
3 C D r 4
3 D E r 4
3 E F r 4
3 F 0 l 3
4 * * r 4
4 _ _ r A
从基数10的输入开始递减计数,而从基数16的0开始递增计数。递减为零时,它将擦除输入块并终止。
10*n + 33
任意完成的指令n
。我不明白代码。
h=i=>(i?h(i>>4):0)+"0123456789abcdef"[i%16]
user81655保存了6个字节。
在这里测试。
有两个前导零,这是规则允许的。
这是一个没有前导零的版本:(47个字节)。
h=i=>(i>15?h(i>>4):"")+"0123456789abcdef"[i%16]
在这里测试。
两者都使用与我的Python答案完全相同的方法。
i&15
会自动转换为整数,并保留小数位数。不需要~~
h=i=>i&&h(i>>4)+"0123456789abcdef"[i&15]
ri{Gmd_A<70s=+\}h;]W%
感谢@MartinBüttner打高尔夫球1个字节!
ri e# Read an integer from STDIN.
{ }h e# Do:
Gmd e# Push qotient and residue of the division by 16.
_A< e# Check if the residue is less than 10.
70s e# Push "70".
= e# Select the character that corresponds to the Boolean.
+ e# Add the character to the digit.
e# This way, 10 -> 'A', etc.
\ e# Swap the quotient on top of the stack.
e# While the quotient is non-zero, repeat the loop.
; e# Pop the last quotient.
]W% e# Reverse the stack.
ri{Gmd_9>7*sc+\}h;]W%
这很有趣。
sm@+jkUTGi_d2_c_.BQ4
解释:
.BQ Convert input to a binary string, e.g. 26 -> '11010'
_c_ 4 Reverse, chop into chunks of 4, and reverse again. We reverse
because chop gives a shorter last element, and we want a shorter
first element: ['1', '0101']
Reversing three times is still shorter than using .[d4 to pad the
binary string to a multiple of 4 with spaces.
m Map across this list:
i_d2 Take the value of the reversed string in binary,
@ and use it as an index into the string:
+jkUTG '0123456789abcdefghijklmnopqrstuvwxyz'
(The alphabet appended to the range 0 to 10)
s Concatenate to create the final string.
s="0123456789ABCDEF"
(sequence(s<$s)!!)
用法示例:sequence(s<$s)!!) $ 1000
-> "00000000000003E8"
。
这将创建一个由所有十六进制数字组成的列表,最多16个十六进制数字。幸运的是,这是按顺序发生的,因此我们只需选择n
第一个即可。
编辑:@毛里斯挤出2个字节。谢谢!
s="0123456789ABCDEF";(sequence(s<$s)!!)
h=lambda i:(i>15 and h(i/16)or'')+"0123456789abcdef"[i%16]
CarpetPython保存了1个字节
运行方式: print h(15)
在此处进行测试(Ideone.com)。
说明:
h=lambda i: # Define h as a function that takes two arguments
(i>15 and h(i/16)or'') # Evaluate h(i/16) if i > 15, else, give ''
+"0123456789abcdef"[i%16] # Append (i%16)'th hexadecimal number.
h=lambda i:(i>15 and h(i/16)or'')+"0123456789abcdef"[i%16]
。
h=lambda i:(i>15 and h(i/16)or'')+chr(48+i%16+i%16/10*7)
感谢@manatwork建议使用递归。
h()(x=({0..9} {A..F})
echo `(($1>15))&&h $[$1/16]`${x[$1%16]})
h(){ x=({0..9} {A..F});echo `(($1>15))&&h $[$1/16]`${x[$1%16]}; }
()
而不是{ ;}
在功能主体周围可以节省更多:)
{[R~] (0..9,'A'..'F').flat[($_,*div 16...^0)X%16]||0}
{[R~] (0..9,'A'..'F').flat[.polymod(16 xx*)]||0}
这将创建一个以整数除(div
)的值序列,直到结果从该序列中0
排除0
$_, * div 16 ...^ 0
然后X
使用模运算符(%
)将序列与()相交16
( … ) X[%] 16
它将这些值用作进入由两个Range 0..9
和'A'..'Z'
( 0 .. 9, 'A' .. 'Z' ).flat[ … ]
最后,~
使用反向(R
)元运算符将它们连接()
[R[~]] …
如果结果为False(空字符串),则返回 0
… || 0
用法:
# (optional) give it a lexical name for ease of use
my &code = { … }
say <15 1000 256 0>.map: &code;
# (F 3E8 100 0)
say code 10¹⁰⁰;
# 1249AD2594C37CEB0B2784C4CE0BF38ACE408E211A7CAAB24308A82E8F10000000000000000000000000
i`16H#\wt9>?7+]wt]xN$hP48+c
这使用的语言/编译器版本5.1.0比此挑战要早。
>> matl
> i`16H#\wt9>?7+]wt]xN$hP48+c
>
> 1000
3E8
i % input number
` % do...
16H#\ % remainder and quotient of division by 16
w % move remainder to top of stack
t9> % does it exceed 9?
? % if so
7+ % add 7 (for letter ASCII code)
] % end if
w % move quotient back to the top
t % duplicate
] % ...while (duplicated) quotient is not zero
x % delete last quotient (zero)
N$h % create vector of all remainders
P % flip vector
48+c % add 48 and convert to char (will be implicitly displayed)
↺a=⬯;ï;ï≫4@a=⩥ḊĀⒸª⩥⁽ṁṇ⸩⨝[ï%Ḑ]+a
好的,我想出了一些其他办法可以解决问题。
它本质上与@ SuperJedi224的ES6解决方案相同,但是有所不同。
看到了⩥ḊĀⒸª⩥⁽ṁṇ⸩⨝
吗?那真是一种花哨的写作方式"0123456789ABCDEF"
。⩥Ḋ
创建一个从0到10 Ⓒª⩥⁽ṁṇ⸩
的范围,创建一个从65到71的范围,并将其转换为ASCII字符串,并Ā...⨝
连接两个范围并将它们连接为一个字符串。这可能是我解决方案中最酷的部分。
↺;ï;ï≫4@ᵴ=(⩥Ḋ⨝+ᶐ)[ï%Ḑ]+ᵴ
我决定像在Pyth中一样添加一个字母字符串。
:
s/\b/_/2
s/[13579]/&;/g
y/123456789/011223344/
s/;0/5/g
s/;1/6/g
s/;2/7/g
s/;3/8/g
s/;4/9/g
s/;_;_;_;_/=/
s/;_;_;__/+/
s/;_;__;_/:/
s/;_;___/>/
s/;__;_;_/</
s/;__;__/?/
s/;___;_/(/
s/;____/*/
s/_;_;_;_/-/
s/_;_;__/^/
s/_;__;_/%/
s/_;___/$/
s/__;_;_/#/
s/__;__/@/
s/___;_/!/
s/____/)/
/[1-9_]/b
y/)!@#$%^-*(?<>:+=/0123456789ABCDEF/
s/^0*//
它不是应对这种挑战的明显语言,但是它的确具有支持输入数字(取决于您的实现)在4000位数和系统可用(虚拟)内存限制之间的优势。我在大约0.6秒内将RSA-1024转换为十六进制,因此扩展性相当好。
它使用连续除以二的方式工作,将进位的每4位累加为一个十六进制数字。我们使用非字母字符表示输出,以便始终在小数输入和十六进制输出之间累积进位,并在最后转换为常规的十六进制。
function h($n){$n&&h($n>>4);echo"0123456789abcdef"[$n&15];}
递归打印功能,打印前导零(在插入>16
前&&
将其删除)
程序,用于64个字节+1 -R
(与一起作为管道运行-nR
)
for(;$n=&$argn;$n>>=4)$s="0123456789abcdef"[$n&15].$s;echo$s?:0;
需要PHP 5.6或更高版本(5.5无法索引字符串文字)
要么
for(;$n=&$argn;$n>>=4)$s=(abcdef[$n%16-10]?:$n%16).$s;echo$s?:0;
需要PHP 5.6或7.0(7.1可以理解否定的字符串索引)
与管道一起运行-nR
或在线尝试它们。
echo+$s
输入0
+
符号会削减第一个字母的输出...因此..?:0
用没有算术运算符的语言执行此操作可能是一个错误。
let h=def (n)(if n.gt(15)h(n.div(16).int!)else "").concat("0123456789abcdef".list!.get(n.mod(16)))
像这样使用:
do
let h = ...
print(h(15))
end
取消高尔夫:
let h = def (n) do
if n.gt(15)
let x = h(n.div(16).int!)
else
let x = ""
x.concat("0123456789abcdef".list!.get(n.mod(16)))
end
,`;4ª@%)4ª@\`╬Xε D`@;7ªD+@9<7*+c+`n
十六进制转储:
2c603b34a640252934a6405c60ce58ee204460403b37a6442b40393c372a2b632b606e
说明:
, Get evaluated input
` `╬ Repeat the quoted function until top of stack is 0
;4ª@% Make a copy of the number mod 16
) Send it to bottom of stack
4ª@\ Integer divide the original copy by 16
X Delete the leftover zero. At this point the stack is
the "digits" of the hex number from LSD to MSD
ε Push empty string
D` `n Essentially fold the quoted function over the stack.
@; Roll up the next lowest digit, make a copy
7ªD+ Add 48
@ Bring up the other copy
9< 1 if it's at least 10, else 0
7* Multiply with 7.
+ Add. This will shift 58->65 and so on.
c Convert to character.
+ Prepend to current string.
请注意,;7ªD+@9<7*+c
相当于4ª▀E
,它将节省8个字节,但是我认为也许将基数b推入字符串的函数可能被认为是“十六进制内置”的过多内容。
v=>eval('for(z="";v;v>>=4)z="0123456789ABCDEF"[v%16]+z')
感谢ןnɟuɐɯɹɐןoɯ和user81655,节省了6个字节。
v=>eval('for(z="";v;v=v/16|0)z="0123456789ABCDEF"[v%16]+z')
v=>{for(z="";v>0;v=v/16|0)z=btoa``Ó]·ã»óÐ1``[v%16]+z;return z}
(双波浪号是单波浪号)==> 64个字符,71个字节。不值得。
v=v/16|0
只是一种复杂的写作方式v>>=4
。
&:88+%"0"+:"9"`7*+\8/2/:!#|_#
,_@ >:#
第一次在Befunge进行真正的高尔夫挑战时,我敢打赌,这是一个单一条件的要求,因为在第二条路线中间的所有这些空间似乎都是浪费的,所以这种方法更短。
您可以在这里逐步进行。部分说明:
&
:输入。
:88+%
:取余数为16。
"0"+
:将其添加到ASCII值0。
:"9"`
:如果结果大于ASCII值9 ...
7*+
:添加7即可将其转换为字母。
\
:将结果字符保存在堆栈中。
8/2/
:除以16舍入。
:!#|_
:如果结果为0,则退出循环。
#
:否则,返回模数步骤。
>:#,_@
(环绕):完成后,按LIFO顺序输出堆栈。
如果> <>具有整数除法,则本来会更短,我们现在必须通过减去模1来模拟整数除法。不过,我认为这使用了一些巧妙的环绕技巧!
>:?!v:f1+%:a(?v v
\-%1:,+1f}+"0"<+7<
!?:r/ro;
第一循环
>:?!v:f1+%:a(?v v
\-%1:,+1f}+"0"<+7<
第一个循环执行经典的转换为十六进制算法。它以16为模(:f1+%
),并检查结果是否小于10(:a(?
)。如果不是,我们需要添加7(7+
),以便从小数点到ASCII表中的大写字母。否则,我们可以通过添加0("0"+
)的ASCII值并将要输出的字符移到堆栈底部来进行操作,因为我们必须以相反的顺序输出它们。然后用整数除以16的结果替换最高值。这通过计算a / b-(a / b)%1(f1+,:1%-
)进行模拟
。循环结束后,堆栈包含以相反的输出顺序排列的十六进制字符和一个0。
第二循环
!?:r<ro;
第二个循环反转列表,并检查top元素是否为0。否则,我们输出字符并再次反转列表以准备下一次迭代。在:
进入时,第二循环将重复,其具有无影响0。