Created
September 29, 2014 20:34
-
-
Save dimitri/d5120b069e601edc312a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; | |
;;; 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))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See also https://gist.github.com/bigos/87aca37517f59860074d