Skip to content

Instantly share code, notes, and snippets.

@dimitri
Created September 29, 2014 20:34
Show Gist options
  • Save dimitri/d5120b069e601edc312a to your computer and use it in GitHub Desktop.
Save dimitri/d5120b069e601edc312a to your computer and use it in GitHub Desktop.
;;;
;;; See https://www.hackerrank.com/challenges/manasa-and-stones
;;;
(defpackage #:manasa-and-stones
(:use :cl))
(in-package #:manasa-and-stones)
(defvar *sample-input* "2
3
1
2
4
10
100")
(defvar *sample-output* "2 3 4
30 120 210 300")
(defun test ()
"test that our code pass the sample"
(string= (solve-all *sample-input*) *sample-output*))
;;;
;;; Data structure
;;;
(defstruct manasa stones a b)
;;;
;;; Algo
;;;
(defun solve (puzzle)
"Solve a given manasa and stones puzzle"
(with-slots (stones a b) puzzle
(let ((solution
(loop :with steps := (- stones 1)
:for n :from 0 :below stones
:collect (+ (* (- steps n) a) ; take a for N steps
(* n b))))) ; take b all other times
(if (< a b) solution (reverse solution)))))
;;;
;;; Low level routines
;;;
(defun solve-all (pathname-or-string &optional output-stream)
"Read the input from PATHNAME-OR-STRING and return the list of computed
solutions."
(let ((input
(typecase pathname-or-string
(pathname (with-open-file (s pathname-or-string) (read-input s)))
(string (with-input-from-string (s pathname-or-string) (read-input s)))))
(output (or output-stream (make-string-output-stream))))
(loop :for puzzle :across input
:do (format-solution output puzzle)
:finally (unless output-stream
(return (get-output-stream-string output))))))
(defun format-solution (stream puzzle)
"Format the solution to PUZZLE in STREAM."
(format stream "~&~{~a~^ ~}" (solve puzzle)))
(defun read-input (stream)
"Read the program input and return"
(flet ((read-test-case (stream)
(let ((stones (parse-integer (read-line stream)))
(a (parse-integer (read-line stream)))
(b (parse-integer (read-line stream))))
(make-manasa :stones stones :a a :b b))))
(handler-case
(let* ((nb-test-cases (parse-integer (read-line stream)))
(test-cases (make-array nb-test-cases :element-type 'manasa)))
(loop :for n :below nb-test-cases
:do (setf (aref test-cases n) (read-test-case stream))
:finally (return test-cases)))
(condition (e)
(format t "Couldn't parse manasa and stones input: ~s" e)))))
@dimitri
Copy link
Author

dimitri commented Sep 29, 2014

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