From 34135dc3fbaef515b78a5d599084d700e4cb66c8 Mon Sep 17 00:00:00 2001
From: Eric Biagioli <ericbiagioli@gmail.com>
Date: Wed, 24 Aug 2016 00:01:18 -0300
Subject: [PATCH] starting

---
 Makefile     |  18 +++++
 exercise.txt |  52 ++++++++++++++
 input1.txt   |   7 ++
 input2.txt   | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++
 solution.hs  |  52 ++++++++++++++
 5 files changed, 329 insertions(+)
 create mode 100644 Makefile
 create mode 100644 exercise.txt
 create mode 100644 input1.txt
 create mode 100644 input2.txt
 create mode 100644 solution.hs

diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..46f164f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,18 @@
+NAME=solution
+
+all: haskell
+
+haskell:
+	ghc $(NAME).hs -o $(NAME)-haskell
+	rm $(NAME).hi $(NAME).o
+
+uploadfile:
+	curl -F file=input1.txt localhost:8000/uploadfile
+
+webservice:
+	ghc -threaded ws.hs -o ws
+	rm ws.hi ws.o
+
+clean:
+	rm -f *.hi *.o $(NAME)
+
diff --git a/exercise.txt b/exercise.txt
new file mode 100644
index 0000000..05c60b9
--- /dev/null
+++ b/exercise.txt
@@ -0,0 +1,52 @@
+Reward system
+
+A company is planning a way to reward customers for inviting their friends.
+They're planning a reward system that will give a customer points for each
+confirmed invitation they played a part into. The definition of a confirmed
+invitation is one where another invitation's invitee invited someone.
+
+The inviter gets (1/2)^k points for each confirmed invitation, where k is the
+level of the invitation: level 0 (people directly invited) yields 1 point,
+level 1 (people invited by someone invited by the original customer) gives 1/2
+points, level 2 invitations (people invited by someone on level 1) awards 1/4
+points and so on. Only the first invitation counts: multiple invites sent to
+the same person don't produce any further points, even if they come from
+different inviters.
+
+Also, to count as a valid invitation, the invited customer must have invited
+someone (so customers that didn't invite anyone don't count as points for the
+customer that invited them).
+
+So, given the input:
+1 2
+1 3 
+3 4
+2 4
+4 5
+4 6
+
+The score is:
+1 - 2.5 (2 because he invited 2 and 3 plus 0.5 as 3 invited 4)
+3 - 1 (1 as 3 invited 4 and 4 invited someone)
+2 - 0 (even as 2 invited 4, it doesn't count as 4 was invited before by 3)
+4 - 0 (invited 5 and 6, but 5 and 6 didn't invite anyone)
+5 - 0 (no further invites)
+6 - 0 (no further invites)
+
+Note that 2 invited 4, but, since 3 invited 4 first, customer 3 gets the
+points.
+
+Write a program that receives a text file with the input and exposes the
+ranking on a JSON format on a HTTP endpoint. Also, create another endpoint to
+add a new invitation.
+
+You should deliver a git repository, or a link to a shared private repository
+on GitHub, Bitbucket or similar, with your code and a short README file
+outlining the solution and explaining how to build and run the code. You should
+follow the functional programming paradigm — Clojure, Common Lisp, Scheme,
+Haskell, ML, F# and Scala are acceptable languages — and we'll analyse the
+structure and readability of the codebase. We expect production-grade code.
+There is no problem in using libraries, for instance for testing or network
+interaction, but please refrain from using a library that already implements
+the core algorithms to solve this problem (e.g. tree or graph algorithms).
+
diff --git a/input1.txt b/input1.txt
new file mode 100644
index 0000000..6c4707f
--- /dev/null
+++ b/input1.txt
@@ -0,0 +1,7 @@
+1 2
+1 3
+3 4
+2 4
+4 5
+4 6
+
diff --git a/input2.txt b/input2.txt
new file mode 100644
index 0000000..4894aad
--- /dev/null
+++ b/input2.txt
@@ -0,0 +1,200 @@
+1 2
+2 3
+3 4
+4 5
+5 6
+6 7
+7 8
+8 9
+9 10
+10 11
+11 12
+12 13
+13 14
+14 15
+15 16
+16 17
+17 18
+18 19
+19 20
+20 21
+21 22
+22 23
+23 24
+24 25
+25 26
+26 27
+27 28
+28 29
+29 30
+30 31
+31 32
+32 33
+33 34
+34 35
+35 36
+36 37
+37 38
+38 39
+39 40
+40 41
+41 42
+42 43
+43 44
+44 45
+45 46
+46 47
+47 48
+48 49
+49 50
+50 51
+51 101
+50 52
+52 102
+50 53
+53 103
+50 54
+54 104
+50 55
+55 105
+50 56
+56 106
+50 57
+57 107
+50 58
+58 108
+50 59
+59 109
+50 60
+60 110
+50 61
+61 111
+50 62
+62 112
+50 63
+63 113
+50 64
+64 114
+50 65
+65 115
+50 66
+66 116
+50 67
+67 117
+50 68
+68 118
+50 69
+69 119
+50 70
+70 120
+50 71
+71 121
+50 72
+72 122
+50 73
+73 123
+50 74
+74 124
+50 75
+75 125
+50 76
+76 126
+50 77
+77 127
+50 78
+78 128
+50 79
+79 129
+50 80
+80 130
+50 81
+81 131
+50 82
+82 132
+50 83
+83 133
+50 84
+84 134
+50 85
+85 135
+50 86
+86 136
+50 87
+87 137
+50 88
+88 138
+50 89
+89 139
+50 90
+90 140
+50 91
+91 141
+50 92
+92 142
+50 93
+93 143
+50 94
+94 144
+50 95
+95 145
+50 96
+96 146
+50 97
+97 147
+50 98
+98 148
+50 99
+99 149
+50 100
+100 150
+69 70
+70 53
+52 54
+59 21
+86 9
+94 43
+59 96
+15 69
+15 40
+93 2
+77 52
+74 66
+39 81
+8 18
+61 68
+63 15
+51 50
+93 77
+28 91
+23 22
+42 1
+95 96
+53 53
+1 46
+10 49
+34 26
+80 21
+88 94
+11 10
+80 24
+10 100
+20 110
+30 120
+30 130
+40 140
+50 150
+60 160
+80 100
+90 100
+56 100
+12 10
+10 12
+100 56
+100 90
+40 140
+10 150
+11 180
+10 190
+24 48
+25 49
+16 48
diff --git a/solution.hs b/solution.hs
new file mode 100644
index 0000000..69c5d3a
--- /dev/null
+++ b/solution.hs
@@ -0,0 +1,52 @@
+import System.IO  
+import Control.Monad
+import Data.Map (Map)
+import qualified Data.Map as Map
+
+main = do  
+  inputStr <- readFile "input1.txt"
+  print (parent (getInput inputStr))
+
+
+{-|
+getInput: Convert the input into a list of pairs. Por example, if the input is 
+----------------------------
+1 2
+1 3
+3 4
+2 4
+4 5
+4 6
+
+----------------------------
+the returnet list is: [[1,2],[1,3],[3,4],[2,4],[4,5],[4,6]]
+-}
+
+getInput :: String -> [[Int]]
+getInput s = map (map read) . map words . filter (not . null) . lines $ s
+
+{-|
+the function Map.fromList creates a map from a list. For example:
+
+Prelude Data.Map Map>  Map.fromList([(1,1),(2,2),(3,3)])
+fromList [(1,1),(2,2),(3,3)]
+
+and
+
+Prelude Data.Map Map>  Map.fromList [(1,1),(2,2),(3,3),(1,4),(1,5)]
+fromList [(1,5),(2,2),(3,3)]
+
+We use this function to compute the parent of each node, when it exists.
+Every time that we have an edge of the form
+
+i -> j
+
+we add (j, i) to the map, indicating that the parent of j is i.
+
+Given that the value is overwritten and we want the first, we reverse the list
+-}
+
+parent :: [[Int]] -> Map Int Int
+parent xs = Map.fromList (map makePair (reverse (map reverse xs)))
+  where makePair x = (x!!0, x!!1)
+
-- 
GitLab