# 写一个99的翻译

99

99（读作“九十九”）是一种全新的Esoteric编程语言（请不要与99混淆，请注意斜体）。您在此挑战中的任务是为99写一个尽可能短的解释器。字节最少的提交将获胜。Tiebreaker转到第一个发布的提交。

# 99规格

99命令式语言。99程序中的每一行都是一条语句，并且在执行过程中，指令指针从第一行开始，依次遍历每行后续的行，并一路执行。当执行了最后一行时，程序结束。Goto语句可能会重新路由指令指针的路径。

``````   9      BLAH        99   9a9bb9c9
9 this line and the next have 6 trailing spaces 9
``````

`````` 9 99 9999
9 9

``````

## 变数

99中的变量都具有一个或多个`9`串在一起的名称（`9+`在正则表达式中）。例如`9``99``9999999999`是完全不同的变量。自然地，存在无限多个（除非存在内存限制）。

## 陈述

99中有五种不同的语句类型。每行99个程序中的包含一个语句。

1.无操作

``````
``````

2.输出

``````V
``````

`V`一行上的单个变量会将其打印到stdout。

``````9
9999
``````

3.输入

`````` V
``````

`````` 9
9
99
99
``````

4.作业

``````V1 V2 V3 V4 V5 ...
``````

`V1 V2``V1 = V2`

`V1 V2 V3``V1 = V2 - V3`

`+`/ `-`迹象保持与每个额外的变量来回切换：

`V1 V2 V3 V4``V1 = V2 - V3 + V4`

``````999           Prints triple-nine divided by nine (111).
999 9 9       Assigns triple-nine to zero (nine minus nine).
999           Prints triple-nine divided by nine (0)
9 999 9       Assigns single-nine to negative nine (zero minus nine).
999 999 9     Adds nine to triple-nine (really subtracts negative nine).
999           Prints triple-nine divided by nine (1).
999 999 9     Adds nine to triple-nine (really subtracts negative nine).
999           Prints triple-nine divided by nine (2).
999 999 9     Adds nine to triple-nine (really subtracts negative nine).
999           Prints triple-nine divided by nine (3).
``````

5.转到（如果全为零则跳转）

`````` V1 V2 V3 V4 V5 ...
``````

``````9          Prints single-nine divided by nine (always 1).
99 9 9     Assigns double-nine to zero.
99 99     Jumps to line zero (top line) if double-nine is zero.
``````

``````99999999                                              Print G.
999 99                                                Set triple-nine to ninety-nine.
9999999999 9999999999 9999999999 99 99 9 9 999 999    Set 10-nine to zero.
99999999999 9999999999                                Set 11-nine to zero.

999                                                   Print triple-nine's value divided by nine. (This is the ninth line.)
99999999                                              Print G.
999 999 9                                             Subtract nine from triple-nine.
99999 999                                            Jump to line 5-nines if triple-nine is zero (ends program).
9 99999999999 9999999999                             Jump to line nine if 10-nine and 11-nine are zero (always jumps).
``````

``````G11G10G9G8G7G6G5G4G3G2G1G
``````

## 额外细节

9

wchargin 2015年

30
@WChargin貌似现在你必须设法得到它99
trlkly

5

5
@Gabe这样的答案可能会得到赏金，但是如果那是唯一的答案，那么该解释器将如何解释？;）

1
@Optimizer，它起作用了：pastebin.com/raw.php?
coredump

16

# CJam，157个字节

``````{:I;_N" 9"+--N/:P:,\$W=){1a*Ab}%:V;{PT):T(=:LS%_{LS#\:,_,({(\{V=}%@{V-1@{2\$*+0@-\}*\;t:V;}{:|T@V=9*?:T;}?}{~\{_V=\1&!{128%c}*o}{VIW):W=it:V;}?}?}R?Tg)TP,<*}g}
``````

### 说明

15
+1。很短。现在，您可以在99中编写CJam解释器吗？;-)
coredump

9
@coredump *
Runer112

Optimizer

26

# Python 3 421 414 410 404 388 395 401字节

### 打高尔夫球：

``````import sys,re
v,i,c,g,L={},0,[re.sub('( ?)[^9]+','\\1',l).rstrip().split(' ')for l in open(sys.argv[1])],lambda i:v.get(i,int(i)//9),len
while-1<i<L(c):
d=c[i];l=L(d);e,*f=d;i+=1
if l>1:
x,*y=f
if e:w=list(map(g,f));v[e]=sum(w[::2])-sum(w[1::2])
elif l==2:j=input();v[x]=int(j)if L(x)%2 else ord(j)
elif~-any(g(j)for j in y):i=g(x)*9
elif e:w=g(e);print(w if L(e)%2 else chr(w%128),end='')``````

### 取消高尔夫：

``````import sys, re

# Intialise variable table.
vars_ = {}
get_var = lambda i: vars_.get(i, int(i)//9)

# Parse commands.
commands=[re.sub('( ?)[^9]+','\\1',l).rstrip().split(' ') for l in open(sys.argv[1])]

# Run until the current instruction index is out of bounds.
index=0
while 0 <= index < len(commands):
# Get the current command and increment the index.
command = commands[index]
l = len(command)
first = command[0]
index += 1

if l > 1:
# Handle the "assignment" command.
if first:
operands = [get_var(i) for i in command[1:]]
vars_[first] = sum(operands[0::2]) - sum(operands[1::2])
# Handle the "input" command.
elif l==2:
inp = input()
vars_[command[1]] = int(inp) if len(command[1]) % 2 else ord(inp)
# Handle the "goto" command.
elif not any(get_var(i) for i in command[2:]):
index = get_var(command[1]) * 9
# Handle the "output" command.
elif first:
val = get_var(first)
print(val if len(first) % 2 else chr(val % 128),end='')``````

``````> python3 ninetynine.py countdown.txt
G11G10G9G8G7G6G5G4G3G2G1G
>
``````

1
@DLosc：关于您的第一点：我也`else`可以删除数字，但是当我较早尝试时，出现语法错误。您的其他技巧还是值得赞赏的！
Mac

3
@coredump：编写规范的方式，每个变量将始终具有可被9整除的值。我发现更简洁的方法是允许变量取任何值，并且仅在需要时乘以九（尤其是在`goto`例程中以及获取变量的默认值时）。就语言的用户而言，这没有什么区别。
Mac

2

DLosc

1
@DLosc：对不起，我误会了-我确实的意思是空格，而不是空格`else`。例如，我试图替换`print(w if L(e)%2 else chr(w%128))``print(w if L(e)%2else chr(w%128))`，并得到了语法异常。
Mac

1

DLosc

16

# 常见的Lisp，1180年 857837 836个字节

``````(defmacro g(g &aux a(~ -1)> d x q(m 0)r v(n t)c(w 0)? u z)(flet((w(n p)(intern(format()"~a~a"p n))))(#1=tagbody %(case(setf c(ignore-errors(elt g(incf ~))))(#\  #2=(when(> w 0)(pushnew w v)(if u()(setq ?(oddp w)))(#5=push(w w'V)u)(setf w 0))(setf z t))(#\9(incf w)(setf >(or >(and n z))z()n()))((#\Newline())#2#(#5#(when u(setf u(reverse u)a(pop u))(if >(if u`(when(every'zerop(list,@u))(setf @,a)(go ^))`(setf,a,(if ?'(read)'(char-code(read-char)))))(if u`(setf,a,(do(p m)((not u)`(-(+,@p),@m))(#5#(pop u)p)(#5#(if u(pop u)0)m)))`(princ,(if ? a`(code-char(mod,a 128)))))))r)(incf m)(setf ?()u()z()>()n t)))(if c(go %))\$(decf m)(setq d(pop r))(if d(#5# d x))(when(=(mod m 9)0)(#5#(w #3=(/ m 9)'L)x)(#5#`(,#3#(go,(w #3#'L)))q))(if(>= m 0)(go \$)))`(let(@,@(mapcar(lambda(n)`(,(w n'V),(/(1-(expt 10 n))9)))v))(#1#,@x(go >)^(case @,@q)>))))
``````
• 词法分析和代码生成交织在一起：我不存储内部表示，而是直接处理每一行。
• 有一个`tagbody`可以执行2个循环：

`````` (... (tagbody % ... (go %) \$ ... (go \$)) result)
``````
• 局部变量在 `&aux`

• 不生成闭包，而是直接生成解释代码
• 等等

# 取消评论

``````(defmacro parse-99
(string &aux
(~ -1) ; current position in string
a      ; first variable in a line
>      ; does current line starts with a leading space?
d      ; holds a statement during code generation
x      ; all statements (labels + expressions)
q      ; all generated case statements
(m 0)  ; count program lines (first increases, then decreases)
r      ; list of parsed expressions (without labels)
v      ; set of variables in program, as integers: 999 is 3
(n t)  ; are we in a new line without having read a variable?
c      ; current char in string
(w 0)  ; currently parsed variable, as integer
?      ; is first variable odd?
u      ; list of variables in current line, as integers
z)     ; is the last read token a space?
(flet((w(n p)
;; produce symbols for 99 variables
;; e.g. (10 'V) => 'V10
;;      (4 'L)  => 'L4
(intern(format()"~a~a"p n))))
(tagbody
parse
(case (setf c
;; read current char in string,
;; which can be NIL if out-of-bounds
(ignore-errors(aref string (incf ~))))

;; Space character
(#\Space
#2=(when(> w 0)
(pushnew w v)            ; we were parsing a variable, add it to "v"
(if u()(setq ?(oddp w))) ; if stack is empty, this is the first variable, determine if odd
(push(w w'V)u)           ; add to stack of statement variable
(setf w 0))              ; reset w for next variable

;; Space can either be significant (beginning of line,
;; preceding a variable), or not. We don't know yet.
(setf z t))

;; Nine
(#\9
(incf w) ; increment count of nines
(setf >(or >(and n z)) ; there is an indent if we were
; starting a newline and reading a
; space up to this variable (or if we
; already know that there is an
; indent in current line).
;; reset z and n
z()n()))

;; Newline, or end of string
((#\Newline())
#2#  ;; COPY-PASTE the above (when(> w 0)...) statement,

;; We can now convert the currently read line.
;; We push either NIL or a statement into variable R.

(push(when u
(setf u (reverse u) ; we pushed, we must reverse
a (pop u))    ; a is the first element, u is popped
(if >
(if u
;; JUMP
`(when(every'zerop(list,@u))(setf @,a)(go ^))

;; STARTS WITH VARIABLE
(if u

;; ARITHMETIC
`(setf,a,(do(p m) ; declare p (plus) and m (minus) lists

;; stopping condition: u is empty
((not u)
;; returned value: (- (+ ....) ....)
`(-(+,@p),@m))

;; alternatively push
;; variables in p and m, while
;; popping u

(push(pop u)p)

;; first pop must succeed, but
;; not necessarly the second
;; one.  using a zero when u
;; is empty covers a lot of
;; corner cases.

(push(if u (pop u) 0) m)))

;; PRINT
`(princ,(if ? a`(code-char(mod,a 128)))))))
r)
;; increase line count
(incf m)
;; reset intermediate variables
(setf ?()u()z()>()n t)))

;; loop until end of string
(if c (go parse))

build
;;; Now, we can add labels in generated code, for jumps

;; decrease line count M, which guards our second loop
(decf m)

;; Take generated statement from R
(setq d(pop r))

;; we pop from R and push in X, which means X will eventually
;; be in the correct sequence order. Here, we can safely

;; We first push the expression, and THEN the label, so that
;; the label ends up being BEFORE the corresponding statement.
(if d(push d x))

;; We can only jump into lines multiple of 9
(when (=(mod m 9)0)
;; Push label
(push(w #3=(/ m 9)'L)x)
;; Also, build a case statement for the jump table (e.g. 2(go L2))
(push`(,#3#(go,(w #3#'L)))q))
;; loop
(if(>= m 0)(go build)))

;; Finally, return the code
`(let(@ ; target of a jump instruction

;; other variables: V3 represents 999 and has a default value of 111
,@(mapcar(lambda(n)`(,(w n'V),(/(1-(expt 10 n))9)))v))

;; build a tagbody, inject statements from X and case statements from Q
;; label ^ points to jump table : we go to ^ each time there is a JUMP
;; label > is the end of program

;; note that if the case does not match any authorized target
;; address, we simply end the programs.
(tagbody,@x(go >)^(case @,@q)>))))``````

# 例

``````(g
"99999999                                              Print G.
999 99                                                Set triple-nine to ninety-nine.
9999999999 9999999999 9999999999 99 99 9 9 999 999    Set 10-nine to zero.
99999999999 9999999999                                Set 11-nine to zero.

999                                                   Print triple-nine's value divided by nine. (This is the ninth line.)
99999999                                              Print G.
999 999 9                                             Subtract nine from triple-nine.
9 99999999999 9999999999                             Jump to line nine if 10-nine and 11-nine are zero (alwa

")``````

``````(LET (@
(V5 11111)
(V11 11111111111)
(V1 1)
(V10 1111111111)
(V2 11)
(V3 111)
(V8 11111111))
(TAGBODY
L0
(PRINC (CODE-CHAR (MOD V8 128)))
(SETF V3 (- (+ V2) 0))
(SETF V10 (- (+ V3 V1 V2 V10) V3 V1 V2 V10))
(SETF V11 (- (+ V10) 0))
L1
(PRINC V3)
(PRINC (CODE-CHAR (MOD V8 128)))
(SETF V3 (- (+ V3) V1))
(WHEN (EVERY 'ZEROP (LIST V3)) (SETF @ V5) (GO ^))
(WHEN (EVERY 'ZEROP (LIST V11 V10)) (SETF @ V1) (GO ^))
(GO >)
^
(CASE @ (0 (GO L0)) (1 (GO L1)))
>))``````

# 命令行

``````(defun main()(parse-99 <PROGRAM>))
(save-lisp-and-die "test-99" :executable t :toplevel #'main)``````

``````\$ sbcl --load boot.lisp
This is SBCL 1.2.8.32-18c2392, an implementation of ANSI Common Lisp.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
[undoing binding stack and other enclosing state... done]
[saving current Lisp image into test-99:
writing 5824 bytes from the read-only space at 0x20000000
writing 3120 bytes from the static space at 0x20100000
writing 55771136 bytes from the dynamic space at 0x1000000000
done]
``````

``````\$ time ./test-99
G11G10G9G8G7G6G5G4G3G2G1G
real    0m0.009s
user    0m0.008s
sys     0m0.000s
``````

6

# TI-84基本（计算器脚本），376个373 377 381字节

``````#Get input from STDIN
:Ans+":"->Str0
#Initialize instruction pointer
:1->I
#Initialize variable set
:DelVar L1999->dim(L1
#Strip out those pesky non-newline/space/9 characters
:For(J,1,length(Ans
:sub(Str0,J,1
:If not(inString(": 9",Ans
:sub(Str0,1,J-1)+sub(Str0,J+1,length(Str0)-J->Str0
:End
#Main interpreting loop
:While I<length(Str0
:sub(Str0,I+1,inString(Str0,":",I+1)-I-1->Str1
:DelVar A" "=sub(Ans,1,1->A
:inString(Str0,":",I+1->I
:If A
:sub(Str1,2,length(Str1)-1->Str1
:End
:length(Str1->L
#0 is Output, 1 is Input, 2 is Assignment, 3 is Goto
:2A+inString(Str1," ->B
:If not(Ans
:Disp L1(L
:If Ans=1
:Then
:Input C
:C->L1(L
:End
#Get those delimited variables
:If B>1
:Then
:"{"+Str1->Str2
:While inString(Ans,"
:inString(Ans,"
:sub(Str2,1,Ans-1)+sub(Str2,Ans+1,length(Str2)-Ans->Str2
:End
:log(expr(Ans)+1->L2
:End
:If B=2
#Gotta expand that -+ pattern
:Ans(2->L1(Ans(1
;Love that summation Σ
:If B=3 and Σ(L2(K),K,2,dim(L2
:Then
:DelVar IFor(K,0,9L2(1
:inString(Str0,":",I+1->I
:End
:End
``````

``````49 3f bb 54 5d 20 39 39 39 04 b5 5d 20 3f 72 04 aa 09 3f d3 4a 2b 31 2b bb 2b 72 3f bb 0c aa 09 2b 4a 2b 31 3f ce b8 bb 0f 2a 3e 29 39 2a 2b 72 3f bb 0c aa 09 2b 31 2b 4a 71 31 11 70 bb 0c aa 09 2b 4a 70 31 2b 72 71 4a 04 aa 09 3f d4 3f d1 49 6b bb 2b aa 09 3f bb 0c aa 09 2b 49 70 31 2b bb 0f aa 09 2b 2a 3e 2a 2b 49 70 31 11 71 49 71 31 04 aa 20 3f bb 54 41 2a 29 2a 6a bb 0c 72 2b 31 2b 31 04 41 3f bb 0f aa 09 2b 2a 3e 2a 2b 49 70 31 04 49 3f ce 41 3f bb 0c aa 20 2b 32 2b bb 2b aa 20 11 71 31 04 aa 20 3f d4 3f bb 2b aa 20 04 4c 3f 32 41 70 bb 0f aa 20 2b 2a 29 04 42 3f ce b8 72 3f de 5d 20 10 4c 11 83 39 3f ce 72 6a 31 3f cf 3f dc 43 3f 39 43 04 5d 20 10 4c 3f d4 3f ce 42 6c 31 3f cf 3f 2a 08 2a 70 aa 20 04 aa 01 3f d1 bb 0f 72 2b 2a 29 3f bb 0f 72 2b 2a 29 3f bb 0c aa 01 2b 31 2b 72 71 31 11 70 bb 0c aa 01 2b 72 70 31 2b bb 2b aa 01 11 71 72 04 aa 01 3f d4 3f c0 bb 2a 72 11 70 31 04 5d 01 3f d4 3f ce 42 6a 32 3f 72 10 32 04 5d 20 10 72 10 31 3f ce 42 6a 33 40 ef 33 5d 01 10 4b 11 2b 4b 2b 32 2b b5 5d 01 3f cf 3f bb 54 49 d3 4b 2b 30 2b 5d 01 10 31 3f bb 0f aa 09 2b 2a 3e 2a 2b 49 70 31 04 49 3f d4 3f d4 2e 76
``````

11

1

Riking

8

Runer112

1
@Timtech但是，仍然存在其他问题。正如我所提到的，缺少字符I / O，缺少变量初始化以及`sub()`命令可以具有零长度并引发错误的多个实例。一旦`sub()`调用固定，恐怕它可能会发现更多问题。
Runer112

1
@Timtech我指的是：“默认情况下，每个变量都分配有其自己的数字表示形式。因此，除非已将其重新分配，否则变量`9`的值为9，而变量的`99`值为99，等等。” 长度为0的字符串可以通过诸如此类生成`""`，但这是一个错误，基本上没有字符串操作命令可以消耗或产生空字符串，包括`sub()`
Runer112

5

# C 426458481497

``````B[99999],*r,*i[9999],V[999],v,w,m,n;unsigned p,s;
main(b,a)char*a[];{r=i[0]=B;m=fopen(a[1],"r");
do if(w=getc(m),n+=w==57,w<33){
if(n){for(v=1,b=n;--b;)v=v*10+1;V[n]=v;*r++=p?-n:n;b=n=0;};
w-32?(*r=p=0,b=i[++s]=++r):(p=b,b=0);}while(w>=0);
while(p<s)if(w=0,r=i[p++],v=*r++)
if(m=v>0,*r){for(;b=*r++;m=-m)w=w+m*V[b]|!m*V[b];m?V[v]=w:(p=w?p:9*V[-v]);
}else~v&1?!m?V[-v]=getchar():putchar(V[v]&127):m?printf("%d",V[v]):scanf("%d",V-v);
}``````

``````B[99999],*r,*i[9999],V[999],v,w,m,n;
unsigned p,s;
main(b,a)char*a[];
{
r=i[0]=B;
m=fopen(a[1],"r");
do if(w=getc(m),n+=w==57,w<33)
{
if(n){for(v=1,b=n;--b;)v=v*10+1;V[n]=v;*r++=p?-n:n;b=n=0;};
w-32?(*r=p=0,b=i[++s]=++r):(p=b,b=0);
}
while (w>=0);
while (p<s)
if (w = 0, r = i[p++], v = *r++)
if (m = v > 0, *r){
for(; b = *r++; m = -m)
w = w + m*V[b] | !m*V[b];
m ? V[v]=w : (p = w ? p : 9*V[-v]);
} else
~v & 1
? !m ? V[-v] = getchar() : putchar(V[v] & 127)
: m ? printf("%d", V[v]) : scanf("%d", V - v);
}``````

1

EMBLEM 2015年

4

``````import Data.List.Split
import System.Environment
a#b=takeWhile(/=a)b
(!)=map
p l=(if ' '#l<'9'#l then[0]else[])++length!(wordsBy(/='9')l)
e l=(\x->div(10^x-1)9)%l where
_%[]=return()
v%([]:r)=v%r
v%([n]:r)=putStr(if odd n then show(v n)else[toEnum\$v n`mod`128])>>v%r
v%((0:n:m):r)|any(/=0)(v!m)=v%r|v n<0=v%[]|1<2=v%drop(9*v n)l
v%((n:m):r)=u n(sum\$zipWith(*)(v!m)(cycle[1,-1]))v%r
u n i v= \x->if x==n then i else v x
``````

``````\$ ./99 i.99
G11G10G9G8G7G6G5G4G3G2G1G
``````

``````import Data.List.Split
import System.Environment

-- The main function takes the first command line argument as a file name,
-- reads the content, splits it into lines, parses each line and evaluates
-- the list of parsed lines.
main = do
(f:_)<-getArgs

-- each line is coverted into a list of integers, which represent the number
-- of 9s (e.g. "999 99 9999" -> [3,2,4]). If there's a space before the first
-- 9, a 0 is put in front of the list (e.g. " 9 9 999" -> [0,1,1,3]).
parse l = (if takeWhile (/=' ') l < takeWhile (/='9') l then [0] else [])
++ map length (wordsBy(/='9') l)

-- The work is done by the helper function 'go', which takes two arguments
--   a) a functions which takes an integer i and returns the value of the
--      variable with i 9s (e.g: input: 4, output: value of 9999). To be
--      exact, the value divided by 9 is returned.
--   b) a list of lines to work on
-- 'eval' starts the process with a function that returns i 1s for every i and
-- the list of the parsed input. 'go' checks which statement has to be
-- executed for the next line and calls itself recursively
eval list = go (\x -> div (10^x-1) 9) list
where
go _ []                  = return ()
go v ([]:r)              = go v r
go v ([n]:r)             = putStr (if odd n then show(v n) else [toEnum (v n`mod`128)]) >> go v r
go v ([0,n]:r)           = do i<-getLine ; go (update n (if odd n then read i else fromEnum\$head i) v) r
go v ((0:n:m):r)
| any (/=0) (map v m) = go v r
| v n < 0             = go v []
| otherwise           = go v (drop (9*v n) list)
go v ((n:m):r)           = go (update n (sum \$ zipWith (*) (map v m) (cycle[1,-1])) v) r

-- updates a function for retrieving variable values.
-- n = position to update
-- i = new value
-- v = the function to update
update n i v = \x->if x==n then i else v x
``````

4

# 的JavaScript（ES6）340 352

• 程序代码为多行字符串
• 输入为数组

JSFiddle测试

``````I=(c,i,k=1e5,
V=v=>v in V?V[v]:v/9 // variable getter with default initial value
)=>(c=>{
for(p=o='';--k&&p<c[L='length'];)
(v=(r=c[p++].split(' '))[S='shift']())? // no leading space
r[r.map(t=>w-=(m=-m)*V(t),w=0,m=1),0]?V[v]=w // Assign
:o+=v[L]&1?V(v):String.fromCharCode(V(v)&127) // Output
(v=r[S]())&&
(r[0]?r.some(t=>V(t))?0:p=9*V(v) // Goto
:(t=i[S](),V[v]=v[L]&1?t:t.charCodeAt()) // Input
)
})(c.replace(/ (?=[^9])|[^9\s]/g,'').split('\n'))  // code cleaning
||o``````

4

# Q / K，490 469

``````M:mod;T:trim;R:read0;S:set;s:" "
f:(rtrim')(f:R -1!`\$.z.x 0)inter\:"9 \n"
k)m:{@[x;&M[!#x;2];-:]}
b:{}
k)p:{1@\$\$[1=M[#x;2];(K x)%9;"c"\$M[(K x)%9;128]];}
k)i:{S[(`\$T x);\$[1=M[#T x;2];9*"J"\$R 0;*9*"i"\$R 0]]}
k)K:{\$[#!:a:`\$x;.:a;"I"\$x]}
k)v:{(S).(`\$*:;+/m@K'1_)@\:T's\:x}
k)g:{\$[&/0=C:K'c:1_J:s\:T x;n::-1+K@*J;|/~0=C;;(d<0)|(d:*C)<#f;exit 0]}
k)r:{`b`p`i`v`g@*&(&/x=s;q&1=c;(e~s)&1=C;(q:e~"9")&1<c:#s\:x;((e:*x)~s)&1<C:#s\:1_x)}
k)n:0;while[~n>#o:(r')f;(o n)f n;n+:1]
\\
``````

``````\$ q 99.q countdown.txt -q
G11G10G9G8G7G6G5G4G3G2G1G
``````

``````M:mod;T:trim;R:read0;S:set
``````

`f` 读取传递到程序中的文件并去除不必要的字符

``````q)f
"99999999"
"999 99"
"9999999999 9999999999 9999999999 99 99 9 9 999 999"
"99999999999 9999999999"
""
""
""
""
""
"999"
"99999999"
"999 999 9"
" 99999 999"
" 9 99999999999 9999999999"
``````

`m` 接受列表/向量并将奇数索引乘以-1

``````q)m 1 2 3 4 5
1 -2 3 -4 5
``````

`b` 只是一个空函数，用于无操作行

`p` 是打印功能。

`K`是检查变量的函数。如果变量存在，则将其返回，否则将仅返回文字。

``````//999 not defined, so just return 999
q)K "999"
999
//Set 999 to 9
q)v "999 9"
//K now returns 9
q)K "999"
9
``````

`v` 是赋值函数。

`g` 是goto函数。

`r` 接受字符串并确定需要应用哪个操作。

3

# Perl，273 266 255 244 238

``````open A,pop;
for(@c=<A>){
y/ 9//cd;s/ +/ /g;s/ \$//;
\$p="((99)+|9+)";\$a='+';
s/^ \$p\$/\$1='\$2'?ord<>:<>/;
s/^\$p\$/print'\$2'?chr\$1%128:\$1/;
s/^ \$p /\\$_=\$1*011unless/&&y/ /|/;
s/ /=/;s/ /\$a=-\$a/ge;
s!9+!\${x.\$&}=\$&/9;"\\$x\$&"!eg}
eval\$c[\$_++]until/-/|\$_>@c
``````

``````\$ perl 99.pl 99beers.99
``````

``````print'\$x99'?chr\$x99999999%128:\$x99999999
\$x999=\$x99
\$x9999999999=\$x9999999999-\$x9999999999+\$x99-\$x99+\$x9-\$x9+\$x999-\$x999
\$x99999999999=\$x9999999999

print''?chr\$x999%128:\$x999
print'\$x99'?chr\$x99999999%128:\$x99999999
\$x999=\$x999-\$x9
\$_=\$x99999*011unless\$x999
\$_=\$x9*011unless\$x99999999999|\$x9999999999
``````

``````open A,pop; # open the source file
for(@c=<A>){ # read all lines into @c and iterate over them
y/ 9//cd; # remove all but spaces and 9's
s/ +/ /g;s/ \$//; # remove duplicate and trailing spaces
\$p="((99)+|9+)";\$a='+';
s/^ \$p\$/\$1='\$2'?ord<>:<>/; # convert input
s/^\$p\$/print'\$2'?chr\$1%128:\$1/; # convert output
s/^ \$p /\\$_=\$1*011unless/&&y/ /|/; # convert goto
s/ /=/;s/ /\$a=-\$a/ge; # convert assignment
s!9+!\${x.\$&}=\$&/9;"\\$x\$&"!eg} # initialize and convert variables
eval\$c[\$_++]until/-/|\$_>@c # run (program counter is in \$_)
``````