re: Daily Coding Puzzles - Oct 29th - Nov 2nd VIEW POST

FULL DISCUSSION
 

Thursday

Calculating with Functions:

This time we want to write calculations using functions and get the results. For example:

seven(times(five())); // must return 35

link

 

Ruby cheat.

substs =
  %w|zero one two three four five six seven eight nine|.
    each_with_index.to_h.merge(
      ")" => "", "(" => "", "times" => "*",
      "plus" => "+", "minus" => "-", "div" => "/")
eval 'seven(times(five()))'.gsub(Regexp.union(substs.keys), substs)
#⇒ 35


 

Python solution:

def perform_operation(operations, number):
    if not operations: return number
    if operations["sign"] == "*":
        return operations["value"] * number
    if operations["sign"] == "+":
        return operations["value"] + number
    if operations["sign"] == "-":
        return number - operations["value"] 
    if operations["sign"] == "/":
        return  number // operations["value"]

zero = lambda operations=None : perform_operation(operations, 0)
one = lambda operations=None : perform_operation(operations, 1)
two = lambda operations=None : perform_operation(operations, 2)
three = lambda operations=None : perform_operation(operations, 3)
four = lambda operations=None : perform_operation(operations, 4)
five = lambda operations=None : perform_operation(operations, 5)
six = lambda operations=None : perform_operation(operations, 6)
seven = lambda operations=None : perform_operation(operations, 7)
eight = lambda operations=None : perform_operation(operations, 8)
nine = lambda operations=None : perform_operation(operations, 9)

get_operation = lambda operation, num : {"sign": operation, "value": num}
plus = lambda num : get_operation("+", num)
minus = lambda num : get_operation("-", num)
times = lambda num : get_operation("*", num)
divided_by = lambda num : get_operation("/", num)

Though I prefer this one from the CodeWars solutions!

def zero(f = None): return 0 if not f else f(0)
def one(f = None): return 1 if not f else f(1)
def two(f = None): return 2 if not f else f(2)
def three(f = None): return 3 if not f else f(3)
def four(f = None): return 4 if not f else f(4)
def five(f = None): return 5 if not f else f(5)
def six(f = None): return 6 if not f else f(6)
def seven(f = None): return 7 if not f else f(7)
def eight(f = None): return 8 if not f else f(8)
def nine(f = None): return 9 if not f else f(9)

def plus(y): return lambda x: x+y
def minus(y): return lambda x: x-y
def times(y): return lambda  x: x*y
def divided_by(y): return lambda  x: x/y
 

seven(times(five())); // must return 35

Why not "must return thirtyFive - a function which is thirty-five"?

Related: Church Numerals.

 
const make = (f, n) => f ? f(n) : n;
const one = f => make(f, 1);
const two = f => make(f, 2);
const three = f => make(f, 3);
const four = f => make(f, 4);
const five = f => make(f, 5);
const six = f => make(f, 6);
const seven = f => make(f, 7);
const eight = f => make(f, 8);
const nine = f => make(f, 9);
const ten = f => make(f, 10);

const plus = a => b => b + a;
const minus = a => b => b - a;
const times = a => b => b * a;
const dividedBy = a => b => b / a;

thanks, it's fun :)

 

Ugly but worked :p
JavaScript

function zero() { return arguments.length === 1 ? arguments[0](0) : 0; }
function one() { return arguments.length === 1 ? arguments[0](1) : 1; }
function two() { return arguments.length === 1 ? arguments[0](2) : 2; }
function three() { return arguments.length === 1 ? arguments[0](3) : 3; }
function four() { return arguments.length === 1 ? arguments[0](4) : 4; }
function five() { return arguments.length === 1 ? arguments[0](5) : 5; }
function six() { return arguments.length === 1 ? arguments[0](6) : 6; }
function seven() { return arguments.length === 1 ? arguments[0](7) : 7; }
function eight() { return arguments.length === 1 ? arguments[0](8) : 8; }
function nine() { return arguments.length === 1 ? arguments[0](9) : 9; }

function plus() {var val = arguments[0]; return function(left) { return left + val; }}
function minus() {var val = arguments[0]; return function(left) { return left - val; }}
function times() {var val = arguments[0]; return function(left) { return left * val; }}
function dividedBy() {var val = arguments[0]; return function(left) { return left / val; }}
 

A groovy version that will do it out to billions. For example:

import static WordMath.*
words {
   oneBillionTwoMillionThreeThousandFiveHundredSixtyFour( plus( one() ) )
}

The only unfortunate thing is in order to support methodMissing it has to be done on instance methods so the words closure hides that fact

class WordMath {

    Map<String,Integer> NAMES_TO_VALUE = [
        "one": 1,
        "two": 2,
        "three": 3,
        "four": 4,
        "five": 5,
        "six": 6,
        "seven": 7,
        "eight": 8,
        "nine": 9,
        "ten": 10,
        "eleven": 11,
        "twelve": 12,
        "thirteen": 13,
        "fourteen": 14,
        "fifteen": 15,
        "sixteen": 16,
        "seventeen": 17,
        "eighteen": 18,
        "nineteen": 19,
        "twenty": 20,
        "thirty": 30,
        "fourty": 40,
        "fifty": 50,
        "sixty": 60,
        "seventy": 70,
        "eighty": 80,
        "ninety": 90,
        "hundred": 100,
        "thousand": 1_000,
        "million": 1_000_000,
        "billion": 1_000_000_000
    ]

    static Integer words(Closure c) {
        c.delegate = new WordMath()
        c()
    }

    def plus( Integer v ) {
        return { v2 -> v2 + v }
    }

    def minus( Integer v ) {
        return { v2 -> v2 - v }
    }

    def times( Integer v ) {
        return { v2 -> v2 * v }
    }

    def dividedBy( Integer v ) {
        return { v2 -> v2 / v }
    }

    def methodMissing( String name, args ) {
        Integer value = parseValue( name )
        if( args.size() > 0 ) {
            args[0]( value )
        } else {
            return value
        }
    }

    Integer parseValue(String name) {
        Integer value = 0
        Integer buffer = 0
        name.replaceAll(/([A-Z])/, ' $1').toLowerCase().split(" ").each { String  number ->
            Integer v = NAMES_TO_VALUE[ number ]
            if( v ) {
                if( v < 100 ) {
                    buffer += v
                } else {
                    buffer *= v
                    if( v > 999 ) {
                        value += buffer
                        buffer = 0
                    }
                }
            } else {
                println("Unknown number ${number}!")
            }
        }
        return value + buffer
    }
}
 
#! /usr/bin/perl
use warnings;
use strict;

sub one   { _num(@_, 1) }
sub two   { _num(@_, 2) }
sub three { _num(@_, 3) }
sub four  { _num(@_, 4) }
sub five  { _num(@_, 5) }
sub six   { _num(@_, 6) }
sub seven { _num(@_, 7) }
sub eight { _num(@_, 8) }
sub nine  { _num(@_, 9) }
sub zero  { _num(@_, 0) }

sub _num { ref $_[0] ? $_[0]->($_[1]) : $_[0] }

sub plus       { my $x = shift; sub {     shift() + $x } }
sub minus      { my $x = shift; sub {     shift() - $x } }
sub Times      { my $x = shift; sub {     shift() * $x } }
sub divided_by { my $x = shift; sub { int(shift() / $x) } }

use Test::More tests => 4;

is four(plus(nine())), 13;
is eight(minus(three())), 5;
is seven(Times(five())), 35;
is six(divided_by(two())), 3;
 

Apparently I've done this kata before...but I don't know if that even helped me this time. It's so hard to wrap my brain around.

function zero() {
  return arguments.length ? arguments[0](0) : 0;
}
function one() {
  return arguments.length ? arguments[0](1) : 1;
}
function two() {
return arguments.length ? arguments[0](2) : 2;
}
function three() {
  return arguments.length ? arguments[0](3) : 3;
}
function four() {
  return arguments.length ? arguments[0](4) : 4;
}
function five() {
  return arguments.length ? arguments[0](5) : 5;
}
function six() {
  return arguments.length ? arguments[0](6) : 6;
}
function seven() {
  return arguments.length ? arguments[0](7) : 7;
}
function eight() {
  return arguments.length ? arguments[0](8) : 8;
}
function nine() {
  return arguments.length ? arguments[0](9) : 9;
}

function plus(b) {
  return function(a) { return Math.floor(a + b) }
}
function minus(b) {
  return function(a) { return Math.floor(a - b) }
}
function times(b) {
  return function(a) { return Math.floor(a * b) }
}
function dividedBy(b) {
  return function(a) { return Math.floor(a / b) }
}
code of conduct - report abuse