example: add 24 game task of Rosetta code
authorArthur Delamare <arthur.delamare@viacesi.fr>
Thu, 21 May 2015 19:35:08 +0000 (15:35 -0400)
committerArthur Delamare <arthur.delamare@viacesi.fr>
Thu, 4 Jun 2015 20:25:54 +0000 (16:25 -0400)
Signed-off-by: Arthur Delamare <arthur.delamare@viacesi.fr>

examples/rosettacode/24_game.nit [new file with mode: 0644]
tests/24_game.inputs [new file with mode: 0644]
tests/sav/24_game.res [new file with mode: 0644]

diff --git a/examples/rosettacode/24_game.nit b/examples/rosettacode/24_game.nit
new file mode 100644 (file)
index 0000000..e6fa12d
--- /dev/null
@@ -0,0 +1,157 @@
+#!/usr/bin/env nit
+#
+# This file is part of NIT ( http://www.nitlanguage.org ).
+# This program is public domain
+
+# Task: 24 game
+# SEE: <http://rosettacode.org/wiki/24_game>
+
+redef class Char
+       fun is_op: Bool do return "-+/*".has(self)
+end
+
+# Get `numbers` and `operands` from string `operation` collect with `gets` in `main` function
+# Fill `numbers` and `operands` array with previous extraction
+fun exportation(operation: String, numbers: Array[Int], operands: Array[Char]) do
+       var previous_char: nullable Char = null
+       var number: nullable Int = null
+       var negative = false
+
+       for i in operation.length.times do
+               var current_char = operation[i]
+               var current_int = current_char.to_i
+
+               if (previous_char == null or previous_char.is_op) and current_char == '-' then
+                       negative = true
+                       continue
+               end
+
+               if current_char.is_digit then
+                       if number == null then
+                               number = current_int
+                       else
+                               number = number * 10 + current_int
+                       end
+               end
+
+               if negative and (current_char.is_op or i == operation.length - 1) then
+                       number = number - number * 2
+                       negative = false
+               end
+
+               if (current_char.is_op or i == operation.length - 1) and number != null then
+                       numbers.add(number)
+                       number = null
+               end
+
+               if not negative and current_char.is_op then
+                       operands.add(current_char)
+               end
+               previous_char = current_char
+       end
+       # Update `numbers` and `operands` array in main function with pointer
+end
+
+# Create random numbers between 1 to 9
+fun random: Array[Int] do
+       return [for i in 4.times do 1 + 9.rand]
+end
+
+# Make mathematical operation with `numbers` and `operands` and add the operation result into `random_numbers`
+fun calculation(random_numbers, numbers: Array[Int], operands: Array[Char]) do
+       var number = 0
+       var temp_numbers = numbers.clone
+
+       while temp_numbers.length > 1 do
+               var operand = operands.shift
+               var a = temp_numbers.shift
+               var b = temp_numbers.shift
+
+               if operand == '+' then number = a + b
+               if operand == '-' then number = a - b
+               if operand == '*' then number = a * b
+               if operand == '/' then number = a / b
+
+               temp_numbers.unshift(number)
+       end
+       if number != 0 then random_numbers.add(number)
+end
+
+# Check if used `numbers` exist in the `random_numbers` created
+fun numbers_exists(random_numbers, numbers: Array[Int]): Bool do
+       for number in numbers do
+               if not random_numbers.count(number) >= numbers.count(number) then return false
+       end
+       return true
+end
+
+# Remove `numbers` when they are used
+fun remove_numbers(random_numbers, numbers: Array[Int]) do
+       for number in numbers do random_numbers.remove(number)
+end
+
+# Check if the mathematical `operation` is valid
+fun check(operation: String): Bool do
+       var previous_char: nullable Char = null
+       var next_char: nullable Char = null
+       var next_1_char: nullable Char = null
+
+       for i in operation.length.times do
+               var current_char = operation[i]
+
+               if i + 1 < operation.length then
+                       next_char = operation[i + 1]
+                       if i + 2 < operation.length then
+                               next_1_char = operation[i + 2]
+                       else
+                               next_1_char = null
+                       end
+               else
+                       next_char = null
+               end
+
+               if not current_char.is_op and not current_char.is_digit then return false
+               if next_char == null and current_char.is_op then return false
+
+               if previous_char == null  then
+                       if next_char == null or next_1_char == null then return false
+                       if current_char == '-' and not next_char.is_digit then return false
+                       if current_char != '-' and not current_char.is_digit then return false
+               else
+                       if next_char != null then
+                               if previous_char.is_digit and current_char.is_op and
+                               not (next_char == '-' and next_1_char != null and
+                               next_1_char.is_digit or next_char.is_digit) then
+                                       return false
+                               end
+                       end
+               end
+               previous_char = current_char
+       end
+       return true
+end
+
+var random_numbers = new Array[Int]
+var operation = ""
+
+random_numbers = random
+while not random_numbers.has(24) and random_numbers.length > 1 do
+       var numbers = new Array[Int]
+       var operands = new Array[Char]
+
+       print "numbers: " + random_numbers.join(", ")
+       operation = gets
+       if check(operation) then
+               exportation(operation, numbers, operands)
+               if numbers_exists(random_numbers, numbers) then
+                       calculation(random_numbers, numbers, operands)
+                       remove_numbers(random_numbers, numbers)
+               else
+                       print "NUMBERS ERROR!"
+               end
+       else
+               print "STRING ERROR!"
+       end
+end
+
+if random_numbers.has(24) then print "CONGRATULATIONS" else print "YOU LOSE"
diff --git a/tests/24_game.inputs b/tests/24_game.inputs
new file mode 100644 (file)
index 0000000..7b80b80
--- /dev/null
@@ -0,0 +1,3 @@
+8/4
+8*2
+16+8
diff --git a/tests/sav/24_game.res b/tests/sav/24_game.res
new file mode 100644 (file)
index 0000000..bcbdec9
--- /dev/null
@@ -0,0 +1,4 @@
+numbers: 8, 4, 8, 8
+numbers: 8, 8, 2
+numbers: 8, 16
+CONGRATULATIONS