沃兹监视器


17

挑战

最近,我进入了8位计算机,并对它们以及其他方法的工作着迷。因此,此代码高尔夫的目标是复制由Steve Wozniak为Apple I设计的Woz Monitor的一部分。

您将存储一个22个十六进制值的数组,其宽度为两个字节(最小值$ 10,最大值$ FF),然后接受n个输入。(通常是两种;像Brainfuck这样的语言可能会遇到困难)。
输入将指向数组中从哪里开始打印以及从哪里停止打印;具有定义行为的输入的起始值将小于或等于终止值。然后,您的程序必须能够打印输入的十六进制之间(包括该十六进制)的每个十六进制值。

一个例子:

Array
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15

Values
FF F4 B6 D7 40 00 00 A4 F0 00 FF 0D 9C 21 65 C4 02 28 90 E7 D6 A5

input first num:
04
input second num:
14
40 00 00 A4 F0 00 FF 0D 9C 21 65 C4 02 28 90 E7 D6

现在,本练习的有趣之处在于,您可以使用任何想要检查用户输入范围的方法。人员输入hello,您的程序有未定义的行为?它退出而不通知?它们都是有效的。

唯一的规则是:

1.在程序启动之前,必须将22个十六进制值的值作为程序的一部分包含在内(不能要求用户输入)。
2.十六进制值的输出必须遵循确切的格式: 00 FF 00 FF 00尾随空格,制表符或行都可以。字符不是。
3.程序不必要求输入带有消息的信息。如果需要,请将“消息”留空。但是,用户必须输入十六进制边界。
4.与您决定的22个十六进制值一样,您必须制作一个实际上从存储中获取值的程序,而不是通过简单地打印值来模仿程序。(例如$ 00的列表)。
5, n个输入,是指您选择的语言识别两个字节宽度的十六进制所需的输入量。例如。(Brainfuck每十六进制将需要两个输入,因此两个必须为四个)。

如果需要澄清,请随时发表评论。

这是代码高尔夫球,所以最短的答案是字节数。

排行榜

这是Martin Ender提供的摘要的排行榜。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

# Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以通过打败旧分数保持标题。例如:

# Ruby, <s>104</s> <s>101</s> 96 bytes


我们是要用户输入两个还是n?我们选择22个十六进制值是什么吗?
xnor

是的,这22个值由您决定。输入值可以是任意数量。我说过,n因为Brainfuck不能输入2个字符串,所以您需要输入第一个字节,然后输入第二个字节作为第一个值,然后再次输入第二个字节,总共输入4个。它们可以是任意数量的。
Finn Rayment

但是,使用这些值,您不能简单地将所有值都设置为00,而要让一个程序模仿实际读取数组的内容。更新问题。
Finn Rayment

如果输入2小于输入1,应该换行还是反向读取?
乔纳森·艾伦

@JonathanAllan完全取决于您。请记住,确保输入正确可能会使您的代码更大。正如规则上方所写,您可以允许任何形式的输入(由您自己决定),如果您愿意,可以导致不确定的行为或错误。
Finn Rayment

Answers:


4

果冻24 21 字节

w@€ØHḅ⁴
ɠǵɠÇr@b⁴ịØHK

选择的值: [00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 1F 10 11 12 13 14 15]

在线试用

如果第二个输入小于第一个输入,则输出相反的顺序。
超出范围的行为是不确定的(例如,“ foo”,“ 14”返回38个值,其中大多数不在数组中,而且许多都不是长度2)

怎么样?

w@€ØHḅ⁴ - Link 1, parse a string as a 1-based hex value e.g. "14"
w@€      - first index (1-based) of each character in
   ØH    - hex digits: "0123456789ABCDEF"                   [2,5]
     ḅ⁴ - convert from base 16                                 37

ɠǵɠÇr@b⁴ịØHK - Main link
ɠ  ɠ          - read a line from stdin               e.g. "04"  "14"
 Ç  Ç         - call the last link (1) as a monad          21    37
  µ           - monadic chain separation
     r@       - inclusive range, with reversed arguments  [   21,   22,...,   36,   37] 
       b⁴     - convert to base 16                        [[1,5],[1,6],...,[2,4],[2,5]]
         ị    - index into
          ØH  - hex digits: "0123456789ABCDEF"            [ "04", "05",..., "13", "14"]
            K - join with spaces

啊,原谅我 你确实是对的。做得好,并排名第一。:)
Finn Rayment,2013年

1
是的,我只是移动并更改了一个偏移量值(现在为1F),这意味着我不需要“正确”解释十六进制输入,也不需要添加16给我两个十六进制数字即可转换回去。
乔纳森·艾伦

4

的JavaScript(ES6),118 115 112 102 82 81个字节

由于ETHproductions节省了1个字节

选择的值:

00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15
-----------------------------------------------------------------
10 10 11 14 10 10 15 15 11 14 10 10 15 15 11 14 10 10 15 15 10 11
  • 提示输入下限,然后提示输入上限(例如0x04/ 0x0f)。
  • 无效的下限将被解释为0x00(最小值)。
  • 无效的上限将被解释为0x15(最大值)。
  • 如果下限大于上限,则不输出任何内容。

alert((1/7+'789').replace(/./g,(v,i)=>i<a|i>b?'':(v|10)+' ',p=prompt,b=p(a=p())))

先前版本(97字节)

生成“真实”十六进制值的伪随机列表:

alert((1/7+'789').replace(/./g,(v,i)=>i<a|i>b?'':(v*7|16).toString(16)+' ',p=prompt,a=p(),b=p()))

顺序:

10 10 17 1c 1e 38 33 31 17 1c 1e 38 33 31 17 1c 1e 38 33 31 38 3f

“消息”:“未捕获的SyntaxError:无效的销毁分配目标”
Finn Rayment

@frayment-这是Chrome,对吗?这很奇怪,因为它[a,b]=prompt().split(' ')在命令行中没有抱怨。无论如何,我更新的答案应该可以解决该问题。
Arnauld

做得好!现在可以使用。奇怪的是Chrome做到了。我在您的JS测试器和开发人员控制台中对其进行了测试。同样的错误。欢迎来到排行榜。
Finn Rayment

您可以使用0x04之类的
Hedi 16'1

1
杜德(Dude),您的替补没有任何问题,在这里工作正常,符合规则。更新您的帖子!:)
Finn Rayment

3

的JavaScript(ES6),107个152 137字节

p=prompt,f=(a=+p(),b=+p(),[x,y,...s]='FFF4B6D7402011A4F0D0FF3D9C2165C4A22890E7D6A5')=>a?f(a-1,b-1,s):x+y+' '+(b?f(a,b-1,s):'');alert(f())

选择的值:

FF F4 B6 D7 40 20 11 A4 F0 D0 FF 3D 9C 21 65 C4 A2 28 90 E7 D6 A5

输入:

  • 输入格式为 0x14
  • 如果任何输入为负或第一个输入大于第二个: InternalError: too much recursion
  • 将打印NaN超出范围。

先前的解决方案:
152个字节:

i=parseInt,p=prompt,f=(a=i(p()),b=i(p()),[x,y,...s]='FFF4B6D7402011A4F0D0FF3D9C2165C4A22890E7D6A5')=>a?f(a-1,b-1,s):x+y+' '+(b?f(a,b-1,s):'');alert(f())

107字节,无效的解决方案(输入丢失):

f=(a,b,[x,y,...s]='FFF4B6D7402011A4F0D0FF3D9C2165C4A22890E7D6A5')=>a?f(a-1,b-1,s):x+y+' '+(b?f(a,b-1,s):'')

1
关!但是您需要能够要求用户输入。我喜欢你的所作所为console.log(...)。;)
Finn Rayment,2013年

@frayment var 和最后一个;不是答案的一部分。它仅用于摘要,这就是为什么我添加了换行符。我将编辑答案。
Hedi

我的坏@Hedi,对此感到抱歉。
Finn Rayment

2

Python,88 87 86字节

@JonathanAllan
节省 1个字节@JonathanAllan 再次节省 1个字节

还更改了代码的基础,现在更好了。

a,b=[int(x,16)for x in raw_input().split()];l=[0]*22
while a<=b:print"%02x"%l[a],;a+=1

选择的价值观:00一切。

与我的C答案相同。但是,这一次,代码从用户处获取了一个输入,要求两个值之间有一个空格,将它们拆分,将它们强制转换为十六进制值,并打印出l数组中包括两个输入值和之间的每个十六进制。由于Python具有宏伟的错误捕获系统,因此不存在缓冲区溢出,因此代码更加安全。该方案是从安全的不确定的行为在一定意义上,当高值较低值之前提交它不会执行。

这对Python 2.x和3.x都适用;如果我写错了,请纠正我,因为我的系统不支持两个口译员,所以我无法使用两个口译员。


2

C ++,98 95 93字节

#include <iostream>
int _[22],a,b;int main(){for(std::cin>>a>>b;b/a++;)printf("%02x ",_[a]);}

我选择的值都是0


欢迎来到编程难题和代码高尔夫球!这是一个很好的答案,但我认为它不能满足挑战的要求。您介意包括您选择的22个十六进制值吗?
ETHproductions

就快到了!唯一的问题是,当我输入值04和时06,我只得到了两个值。我怀疑这些是0506值。您需要提供介于输入值之间(包括输入值)的所有值。
Finn Rayment

1
@frayment,哦,对了,已修复!
法提赫·巴基尔

1

Perl,79 45 41字节

“最低价值$ 10”(示例中的最低价值为$ 00)是错字吗?

这是一个相当无聊的perl答案,只有41个字节(以前是46个字节,然后我一直看到空格,可以忽略的括号)。分两行输入。

printf'%02X ',$_ for(4..26)[hex<>..hex<>]

数据为列表04..1A

在我对打包操作太聪明之前。立即输入其输入字节,例如“ 020E”将打印第2-14个条目

printf'%02X ',$_ for sub{(4..26)[shift..shift]}->(unpack'CC',pack'H4',<>)

可能尝试使用全0 substrprintf'%*vX'... 和... 更多打高尔夫球,这使我的回答更长了。48个字符(使用ascii'7'字符串,十六进制37作为数据)

printf'%*vX',' ',substr 7x22,$s=hex<>,1+hex<>-$s

1

CJam,22个字节

{r:~Gb}2*37m!s2/\)<>S*

选择的值:

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15
-----------------------------------------------------------------
13 76 37 53 09 12 26 34 50 46 31 59 79 58 15 80 90 24 00 00 00 00

在线尝试


1

Scala,45个字节

(_:Int)to(_:Int)map(x=>f"$x%02X")mkString " "

取消高尔夫:

(a:Int,b:Int)=>a.to(b).map(x=>f"$x%02X").mkString(" ")

用途00FF作为值,但对于高至2147483647。


error: ')' expected but string literal found.a.to(b).map(
Finn Rayment

不知道是我还是什么。:/我应该尝试运行什么?
Finn Rayment

@frayment可能是因为字符串插值,这是在Scala 2.10.0中引入的
corvus_192

那么,您将其内置在哪个版本中?2.9?
Finn Rayment

@frayment我使用了2.11.7 REPL
corvus_192 '16

1

C,176个 175 161字节

1个字节保存感谢@JonathanAllan到
海量的帮助感谢@Downvoter救了我14个字节!

int main(){int a[44]={0};char s[2];scanf("%s",s);int b=(int)strtol(s,0,16);scanf("%s",s);int c=(int)strtol(s,0,16);while(b<=c){printf("%d%d ",a[b],a[b+1]);b++;}}

在线尝试!

选择的价值观:00一切。

不公开的答案:

int main() {
    int a[44] = {0};
    char s[2];
    scanf("%s", s);
    int b = (int) strtol(s, 0, 16);
    scanf("%s", s);
    int c = (int) strtol(s, 0, 16);
    while (b <= c) {
        printf("%d%d ", a[b], a[b+1]);
        b++;
    }
}

解决这个问题的技巧是接受两个输入,然后尝试将它们转换为十六进制字符串,然后转换为整数。由于没有错误检查或类似的方法,未定义的行为只是引发错误并破坏程序。用户需要输入两个输入,但是我的Eclipse CDT编译器似乎允许我将它们都输入在同一行上,并在两者之间留有空格。

它们必须以正确的顺序排列,因为在较小的值之前根本不会运行while-loop的情况下,请求较大的值。

事实是,也没有缓冲区溢出保护,因此我可以简单地请求一些荒谬的东西,例如从$ 0到$ FFFF的范围,并且我将从a[44]数组内存分配的开始就获取计算机内存中的所有内容。,直到65536值。


输入格式中的单个空格字符可与输入流中的任意数量的空格匹配,尽管大多数scanf格式无论如何都会跳过空格,就其而言,为什么不切出中间人并%x直接使用呢?
尼尔

为什么不使用char s[2]代替malloc东西呢?malloc无论如何,在C中都不需要强制转换的返回值。
cadaniluk '16

@Neil如果您谈论的是printf("%d%d ", ...)零件,只需将格式替换为%x仅返回0而不是00s,就不会将它们隔开。
Finn Rayment

@Downvoter非常感谢!我没想到。现在编辑答案。
Finn Rayment

不,我仍在谈论scanf
尼尔

1

GNU sed,209 + 1(r标志)= 210字节

1{h
s:.*:,00 FF,01 F4,02 B6,03 D7,04 40,05 00,06 00,07 A4,08 F0,09 00,0A FF,0B 0D,0C 9C,0D 21,0E 65,0F C4,10 02,11 28,12 90,13 E7,14 D6,15 A5:
H;d}
G;s:\n(.*)\n.*(,\1.*):\n\2:
s:(.*)\n(.*,\1 ..).*:\2:
s:,..::g

在线尝试!我希望允许在输出中出现一个领先的空格。

运行示例:

me@LCARS:/PPCG$ echo -e "06\n0F" | sed -rf table_lookup.sed
 00 A4 F0 00 FF 0D 9C 21 65 C4
me@LCARS:/PPCG$ echo -e "13\n13" | sed -rf table_lookup.sed
 E7

说明:存储的22个十六进制值与OP示例中的值相同

value | FF F4 B6 D7 40 00 00 A4 F0 00 FF 0D 9C 21 65 C4 02 28 90 E7 D6 A5
-------------------------------------------------------------------------
index | 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15

开始和结束索引在单独的行上读取。输出是一行,其中表值在该索引范围(含)范围内。未定义的输入将写入多行无效的输出。

# store START index in hold space
1{h
# generate the table
s:.*:,INDEX1 VALUE1,INDEX2 VALUE2,°°°:
# append table to hold space and delete pattern space
H;d}
# read END index, append hold space (pattern space format is: END\nSTART\nTABLE)
G
# delete table entries up to, but excluding, the START index (END\nTABLE')
s:\n(.*)\n.*(,\1.*):\n\2:
# delete table entries starting from, but excluding, the END index (TABLE'')
s:(.*)\n(.*,\1 ..).*:\2:
# remove the indexes and print (implicitly) the resulting values
s:,..::g

1

PHP,106105104 96 + 2字节

eval($s='for($a=a;$a++<c;)$$a=hexdec($argv[++$i]);while($b<=$c)printf("%02X ",ord($s[$b++]));');

要么

eval($s='for($a=a;$a++<c;)$$a=hexdec($argv[++$i]);');while($b<=$c)printf("%02X ",ord($s[$b++]));

php -nr '<code>' <lowindex> <highindex>; 转义代码中的单引号。
...或在线测试

dechex 只要字符是十六进制数字,就将输入解释为十六进制字符串,
0如果输入以其他内容开头则将输入如果。

如果第一个值大于第二个值,则不打印任何内容。

选择的值:

00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15
-----------------------------------------------------------------
66 6F 72 28 24 61 3D 61 3B 24 61 2B 2B 3C 63 3B 29 24 24 61 3D 68

(已执行代码的前22个ASCII代码)

要么

for($a=a;$a++<c;)eval($s='$$a=hexdec($argv[++$i]);');while($b<=$c)printf("%02X ",ord($s[$b++]));

具有以下值:

00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15
-----------------------------------------------------------------
24 24 61 3D 68 65 78 64 65 63 28 24 61 72 67 76 5B 2B 2B 24 69 5D 

答案通常包含该<?php块吗?
Finn Rayment

@frayment不是,如果您使用-r。如果需要将其存储到文件中,请使用short open标签<?
泰特斯(Titus)

常量azProgramingPuzles_CGolf未定义。ProgramingPuzles_CGolf到底是哪里来的?:/
Finn Rayment

@frayment这些是通知。如果您不喜欢它们,请重新stderr选择/dev/null。PHP将未定义的常量评估为字符串。
泰特斯(Titus)

但是它们作为语法错误出现,我无法运行该程序。
Finn Rayment

1

Apple II 6502组装,75字节

字节码:

A9 46 85 36 A9 10 85 37 A0 00 98 20 DA FD A9 A0 
20 ED FD C0 42 D0 F3 20 93 FE A2 FC 20 1B FD 9D 
04 01 E8 D0 F7 86 31 A9 8D 8D 04 02 20 A7 FF B5 
3C 0A 75 3C 95 3C CA 10 F6 A6 3D BD 05 02 20 ED 
FD E8 E4 3C D0 F5 99 05 02 C8 60

拆卸:

  LDA    #<+
  STA    CSWL
  LDA    #>+
  STA    CSWH    ;redirect stdout
  LDY    #$00
- TYA
  JSR    PRBYTE  ;print number
  LDA    #$A0    ;space
  JSR    COUT    ;print space
  CPY    #$42    ;22*3
  BNE    -
  JSR    SETVID  ;restore stdout
  LDX    #$FC
- JSR    KEYIN   ;fetch a key
  STA    $0104,X ;store to $200+
  INX
  BNE    -       ;four keys
  STX    MODE    ;set internal flags
  LDA    #$8D
  STA    $0204   ;set key delimiter
  JSR    GETNUM  ;convert keys to hex values
- LDA    A1L,X   ;fetch value
  ASL
  ADC    A1L,X   ;multiply by 3
  STA    A1L,X   ;store value
  DEX
  BPL    -       ;both inputs
  LDX    A1H     ;first input
- LDA    $0205,X ;fetch from index
  JSR    COUT    ;print character
  INX
  CPX    A1L
  BNE    -       ;until second input
+ STA    $0205,Y ;fall through to save a byte
  INY
  RTS

它在内存中形成一个看起来像输出的数组。选择的值是:

00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15
-----------------------------------------------------------------
00 03 06 09 0C 0F 12 15 18 1B 1E 21 24 27 2A 2D 30 33 36 39 3C 3F

用户按四个键设置输入。


Oooo使用Apple自己的代码。做得非常好。
Finn Rayment
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.