Skip to content

Instantly share code, notes, and snippets.

@Centaur
Last active May 19, 2018 05:08
Show Gist options
  • Save Centaur/090c7bddff7f90fc76d3 to your computer and use it in GitHub Desktop.
Save Centaur/090c7bddff7f90fc76d3 to your computer and use it in GitHub Desktop.
Scala vs Clojure

Treat or Trick

Everyone knows what Halloween is and how children love it. Children in costumes travel from house to house asking for treats with a phrase "Trick or treat". After that, they divide the treats equally among all. This year, they collected tons of candies, and need your help to share everything equally. You know that children receive different number of candies depending on their costume: vampire gets 3 candies from one house, zombie – 4 candies, and witch – 5 candies. That is, three children in three different costumes get 3+4+5=12 candies from one house.

Input sample:

The first argument is a path to a file. Each line includes a test case with number of vampires, zombies, witches, and houses that they visited.

For example:

Vampires: 1, Zombies: 1, Witches: 1, Houses: 1
Vampires: 3, Zombies: 2, Witches: 1, Houses: 10

Output sample:

You need to print number of candies that each child will get. If the number is not integer, round it to the lower: for example, if the resulting number is 13.666, round it to 13.

For example:

4
36
(ns com.gtan.mile1.candies
(:require [clojure.string :refer [split trim]]))
(def count-candy {"Vampires" 3 "Zombies" 4 "Witches" 5})
(defn calc [str]
(let [pairs (for [costume (split str #",")] (split costume #":"))
m (into {} (for [[key number] pairs]
[(trim key) (Integer/parseInt (trim number))]))
candies (keys count-candy)]
(quot
(* (apply + (for [candy candies] (* (m candy) (count-candy candy))))
(m "Houses"))
(apply + (for [candy candies] (m candy))))))
val count_candies = Map("Vampires" -> 3, "Zombies" -> 4, "Witches" -> 5)
def calc(child: String): Int = {
val m = child.split(",") map (_ split ":") map {
case Array(k, v) => k.trim -> v.trim.toInt
} toMap
val childCount = m.filterKeys(_ != "Houses").values.sum
(count_candies.keys map { key => count_candies(key) * m(key)} sum) * m("Houses") / childCount
}
@Centaur
Copy link
Author

Centaur commented Nov 6, 2015

高下立分。

@escherize
Copy link

I noticed both those examples don't satisfy the promt... Probably you'd look to something like this.

(defn h [s]
  (let [[v z w h] (map read-string (re-seq #"\d+" s))]
    (int (/ (* (+ (* v 3) (* z 4) (* w 5)) h) (+ v z w)))))

Then:

(h "Vampires: 3, Zombies: 2, Witches: 1, Houses: 10")
;;=> 36

If you want to read / write (which neither version does):

(require '[clojure.string :as str])

(defn halloween [in-path out-path]
  (->> (slurp in-path)
       str/split-lines
       (mapv h)
       (str/join "\n")
       (spit out-path)))

@krishnact
Copy link

Groovy example won't hurt, right? Including file reading, which Scala and Clojure versions are not doing.

void printShares(String filename) {
	def weights = [Vampires: 3, Zombies: 4, Witches: 5, Houses: 0]
	new File(filename).text.eachLine{String aLine->
		def data = Eval.me("["+aLine+"]");
		def candies  = (data.collect{weights[it.key]*it.value}.sum() * data.Houses)
		def children = (data.values().sum() - data.Houses)
		println ((int)(candies/children))
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment