@@ -0,0 +1,85 @@
1+---
2+title: Scala
3+sort: 4
4+next: true
5+---
6+
7+# Scala
8+
9+From [Steve Randy Waldman](https://github.com/swaldman/nnnock/blob/master/src/main/scala/com/mchange/sc/v1/nnnock/package.scala):
10+
11+```
12+package object nnnock {
13+
14+ sealed trait Noun;
15+ case class Atom( value : Int ) extends Noun;
16+ case class Cell( head : Noun, tail : Noun ) extends Noun;
17+ implicit def toAtom( value : Int ) : Atom = Atom( value );
18+ implicit def toInt( atom : Atom ) : Int = atom.value;
19+
20+ def nock( a : Noun ) : Noun = *(a)
21+
22+ object Cell {
23+ private def apply( nl : List[Noun] ) : Cell = {
24+ nl match {
25+ case a :: b :: Nil => Cell(a, b);
26+ case a :: b :: c :: Nil => Cell(a, Cell(b, c));
27+ case a :: b :: c :: tail => Cell(a, this.apply( b :: c :: tail ) );
28+ }
29+ }
30+ def apply(a : Noun, b : Noun, tail : Noun*) : Cell = apply( a :: b :: tail.toList );
31+ }
32+
33+ def ?( noun : Noun ) : Noun = noun match {
34+ case _ : Cell => 0;
35+ case _ : Atom => 1;
36+ }
37+
38+ @tailrec def plus( noun : Noun ) : Noun = noun match {
39+ case a : Atom => 1 + a;
40+ case c : Cell => plus( c ); //intentional endless spin
41+ }
42+
43+ def heq( noun : Noun ) : Atom = noun match {
44+ case Cell( a : Atom, b : Atom ) => if ( a == b ) 0 else 1;
45+ case Cell( a : Cell, b : Atom ) => 1;
46+ case Cell( a : Atom, b : Cell ) => 1;
47+ case Cell( a : Cell, b : Cell ) => if ((heq( Cell( a.head, b.head ) ) | heq( Cell( a.tail, b.tail ) )) == 0) 0 else 1;
48+ case a : Atom => heq( a ); //intentional endless spin
49+ }
50+
51+ def /( noun : Noun ) : Noun = noun match {
52+ case Cell(Atom(1), a) => a;
53+ case Cell(Atom(2), Cell(a, b)) => a;
54+ case Cell(Atom(3), Cell(a, b)) => b;
55+ case Cell(Atom(value), b ) => {
56+ val a = value / 2;
57+ val num = if ( value % a == 0 ) 2 else 3;
58+ /(Cell(num, /(Cell(a, b))));
59+ }
60+ case a => /( a ); //intentional endless spin
61+ }
62+
63+ def *( noun : Noun ) : Noun = noun match {
64+ case Cell( a, Cell(Cell(b, c), d) ) => Cell( *(Cell(a,b,c)), *(Cell(a,d)) );
65+ case Cell( a, Cell(Atom(value), tail) ) => {
66+ (value, tail) match {
67+ case (0, b) => /( Cell(b, a) );
68+ case (1, b) => b;
69+ case (2, Cell(b, c)) => *( Cell( *( Cell(a,b) ), *( Cell(a,c) ) ) );
70+ case (3, b) => ?( *( Cell(a,b) ) );
71+ case (4, b) => plus( *( Cell(a,b) ) );
72+ case (5, b) => heq( *( Cell(a,b) ) );
73+ case (6, Cell(b, Cell(c, d))) => *( Cell(a,2,Cell(0,1),2,Cell(1,c,d),Cell(1,0),2,Cell(1,2,3),Cell(1,0),4,4,b) ); //wtf?
74+ case (7, Cell(b, c)) => *( Cell(a,2,b,1,c) );
75+ case (8, Cell(b, c)) => *( Cell(a,7,Cell(Cell(7,Cell(0,1),b),0,1),c) ); //wtf2
76+ case (9, Cell(b, c)) => *( Cell(a,7,c,2,Cell(0,1),0,b) );
77+ case (10, Cell(Cell(b,c),d)) => *( Cell(a,8,c,7,Cell(0,3),d) );
78+ case (10, Cell(b, c)) => *( Cell(a,c) );
79+ case _ => *( noun ); //intentional endless spin
80+ }
81+ }
82+ case a => *( a ); //intentional endless spin
83+ }
84+}
85+```