{"id":20009898,"url":"https://github.com/plsyssec/00-warmup","last_synced_at":"2026-05-08T22:35:26.365Z","repository":{"id":144629335,"uuid":"80171120","full_name":"PLSysSec/00-warmup","owner":"PLSysSec","description":"Homework Assignment #0","archived":false,"fork":false,"pushed_at":"2016-09-28T20:49:12.000Z","size":17,"stargazers_count":0,"open_issues_count":0,"forks_count":3,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-03-02T01:44:10.062Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PLSysSec.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-01-27T01:02:08.000Z","updated_at":"2018-09-27T17:26:54.000Z","dependencies_parsed_at":"2023-07-04T19:35:34.959Z","dependency_job_id":null,"html_url":"https://github.com/PLSysSec/00-warmup","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/PLSysSec/00-warmup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLSysSec%2F00-warmup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLSysSec%2F00-warmup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLSysSec%2F00-warmup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLSysSec%2F00-warmup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PLSysSec","download_url":"https://codeload.github.com/PLSysSec/00-warmup/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PLSysSec%2F00-warmup/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32800434,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"ssl_error","status_checked_at":"2026-05-08T08:22:45.650Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T07:17:25.774Z","updated_at":"2026-05-08T22:35:26.350Z","avatar_url":"https://github.com/PLSysSec.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"---\ntitle: HW 0, due 9/30/2016\nheaderImg: angles.jpg\n---\n\n## Download\n\n```bash \n$ git clone https://github.com/ucsd-cse131/00-warmup.git\n$ cd 00-warmup/\n```\n\n## Overview\n\nThis is a _warm up_ assignment which will\n\n* refresh your memory of functional programming from CSE 130, and\n* provide a quick introduction to Haskell.\n\nTo this end, you will, reimplement certain problems from\nCSE 130 in Haskell. Recall that the problems require\nrelatively little code ranging from 2 to 15 lines.\nIf any function requires more than that, you can be\nsure that you need to rethink your solution.\n\n1. [lib/Hw0.hs](/lib/Hw0.hs) has skeleton functions with\n   missing bodies that you will fill in,\n2. [tests/Test.hs](/tests/Test.hs) has some sample tests,\n   and testing code that you will use to check your\n   assignments before submitting.\n\nYou should only need to modify the parts of the files which say:\n\n```haskell\nerror \"TBD: ...\"\n```\n\nwith suitable Haskell implementations.\n\n**Note:** Start early, to avoid any unexpected shocks late in the day.\n\n## Assignment Testing and Evaluation\n\nYour functions/programs **must** compile and run on `ieng6.ucsd.edu`.\n\nMost of the points, will be awarded automatically, by\n**evaluating your functions against a given test suite**.\n\n[Tests.hs](/tests/Test.hs) contains a very small suite\nof tests which gives you a flavor of of these tests.\nWhen you run\n\n```shell\n$ stack test\n```\n\nYour last lines should have\n\n```\nAll N tests passed (...)\nOVERALL SCORE = ... / ...\n```\n\n**or**\n\n```\nK out of N tests failed\nOVERALL SCORE = ... / ...\n```\n\n**If your output does not have one of the above your code will receive a zero**\n\nIf for some problem, you cannot get the code to compile,\nleave it as is with the `error ...` with your partial\nsolution enclosed below as a comment.\n\nThe other lines will give you a readout for each test.\nYou are encouraged to try to understand the testing code,\nbut you will not be graded on this.\n\n## Submission Instructions\n\nTo submit your code, just do:\n\n```bash\n$ make turnin \n```\n\n`turnin` will provide you with a confirmation of the\nsubmission process; make sure that the size of the file\nindicated by `turnin` matches the size of your file.\nSee the ACS Web page on [turnin](http://acs.ucsd.edu/info/turnin.php)\nfor more information on the operation of the program.\n\n## Problem 1: [Roots and Persistence](http://mathworld.wolfram.com/AdditivePersistence.html)\n\n### (a) 10 points\n\nFill in the implementation of\n\n```haskell\nsumList :: [Int] -\u003e Int\nsumList xs = error \"TBD:sumList\"\n```\n\nthat such that `sumList xs` returns the sum of the integer elements of\n`xs`. Once you have implemented the function, you should get the following\nbehavior at the prompt:\n\n```haskell\nghci\u003e sumList [1, 2, 3, 4]\n10\n\nghci\u003e sumList [1, -2, 3, 5]\n7\n\nghci\u003e sumList [1, 3, 5, 7, 9, 11]\n36\n```\n\n## (b) 10 points\n\nFill in the implementation of the function\n\n```haskell\ndigitsOfInt :: Int -\u003e [Int]\ndigitsOfInt n = error \"TBD:digitsOfInt\"\n```\n\nsuch that `digitsOfInt n`\n\n* returns `[]` if `n` is not positive, and otherwise\n* returns the list of digits of `n` in the order in which they appear in `n`.\n\nOnce you have implemented the function, you should get the following:\n\n```haskell\nghci\u003e digitsOfInt 3124\n[3, 1, 2, 4]\n\nghci\u003e digitsOfInt 352663\n[3, 5, 2, 6, 6, 3]\n```\n\n### (c) 10+10 points\n\nConsider the process of taking a number, adding its digits,\nthen adding the digits of the number derived from it, etc.,\nuntil the remaining number has only one digit.\nThe number of additions required to obtain a single digit\nfrom a number `n` is called the *additive persistence* of `n`,\nand the digit obtained is called the *digital root* of `n`.\n\nFor example, the sequence obtained from the starting number\n`9876` is `9876`, `30`, `3`, so `9876` has an additive\npersistence of `2` and a digital root of `3`.\n\nWrite two functions\n\n```haskell\nadditivePersistence :: Int -\u003e Int\nadditivePersistence n = error \"TBD:additivePersistence\"\n\ndigitalRoot :: Int -\u003e Int\ndigitalRoot n = error \"TBD:digitalRoot\"\n```\n\nthat take positive integer arguments `n` and return respectively\nthe additive persistence and the digital root of `n`. Once you\nhave implemented the functions, you should get the following\nbehavior at the prompt:\n\n```haskell\nghci\u003e additivePersistence 9876\n2\n\nghci\u003e digitalRoot 9876\n3\n```\n\n## Problem 2: Palindromes\n\n### (a) 15 points\n\nWithout using any built-in functions (e.g. `reverse`),\nwrite an function:\n\n```haskell\nlistReverse :: [a] -\u003e [a]\nlistReverse xs = error \"TBD:listReverse\"\n```\n\nsuch that `listReverse [x1,x2,...,xn]` returns the list `[xn,...,x2,x1]`\ni.e. the input list but with the values in reversed order.\nYou should get the following behavior:\n\n```haskell\nghci\u003e listReverse [1, 2, 3, 4]\n[4, 3, 2, 1]\n\nghci\u003e listReverse [\"a\", \"b\", \"c\", \"d\"]\n[\"d\", \"c\", \"b\", \"a\"]\n```\n\n###(b) 10 points\n\nA *palindrome* is a word that reads the same from left-to-right and\nright-to-left. Write a function\n\n```haskell\npalindrome :: String -\u003e Bool\npalindrome w = error \"TBD:palindrome\"\n```\n\nsuch that `palindrome w` returns `True` if the string is a palindrome and\n`False` otherwise. You should get the following behavior:\n\n```haskell\nghci\u003e palindrome \"malayalam\"\nTrue\nghci\u003e palindrome \"myxomatosis\"\nFalse\n```\n\n## Problem 3: Folding Warm-Up\n\n### (a) 15 points\n\nFill in the skeleton given for `sqsum`,\nwhich uses `foldl'` (the equivalent of Ocaml's `List.fold_left`)\nto get a function\n\n```haskell\nsqSum :: [Int] -\u003e Int\n```\n\nsuch that `sqSum [x1,...,xn]` returns the integer `x1^2 + ... + xn^2`\n\nYour task is to fill in the appropriate values for\n\n1. the folding function `f` and\n2. the base case `base`.\n\nOnce you have implemented the function, you should get\nthe following behavior:\n\n```haskell\nghci\u003e sqSum []\n0\n\nghci\u003e sqSum [1, 2, 3, 4]\n30\n\nghci\u003e sqSum [(-1), (-2), (-3), (-4)]\n30\n```\n\n### (b) 30 points\nFill in the skeleton given for `pipe` which uses `foldl'`\nto get a function\n\n```haskell\npipe :: [(a -\u003e a)] -\u003e (a -\u003e a)\n```\n\nsuch that `pipe [f1,...,fn] x` (where `f1,...,fn` are functions!)\nshould return `f1(f2(...(fn x)))`.\n\nAgain, your task is to fill in the appropriate values for\n\n1. the folding function `f` and\n2. the base case `base`.\n\nOnce you have implemented the function, you should get\nthe following behavior:\n\n```haskell\nghci\u003e pipe [] 3\n3\n\nghci\u003e pipe [(\\x -\u003e x+x), (\\x -\u003e x + 3)] 3\n12\n\nghci\u003e pipe [(\\x -\u003e x * 4), (\\x -\u003e x + x)] 3\n24\n```\n\n\n### (c) 20 points\n\nFill in the skeleton given for `sepConcat`,\nwhich uses `foldl'` to get a function\n\n```haskell\nsepConcat :: String -\u003e [String] -\u003e String\n```\n\nIntuitively, the call `sepConcat sep [s1,...,sn]` where\n\n* `sep` is a string to be used as a separator, and\n* `[s1,...,sn]` is a list of strings\n\nshould behave as follows:\n\n\n* `sepConcat sep []` should return the empty string `\"\"`,\n* `sepConcat sep [s]` should return just the string `s`,\n* otherwise (if there is more than one string) the output\n  should be the string `s1 ++ sep ++ s2 ++ ... ++ sep ++ sn`.\n\nYou should only modify the parts of the skeleton consisting\nof `error \"TBD\" \"`. You will need to define the function `f`,\nand give values for `base` and `l`.\n\nOnce done, you should get the following behavior:\n\n```haskell\nghci\u003e sepConcat \", \" [\"foo\", \"bar\", \"baz\"]\n\"foo, bar, baz\"\n\nghci\u003e sepConcat \"---\" []\n\"\"\n\nghci\u003e sepConcat \"\" [\"a\", \"b\", \"c\", \"d\", \"e\"]\n\"abcde\"\n\nghci\u003e sepConcat \"X\" [\"hello\"]\n\"hello\"\n```\n\n### (d) 10 points\n\nImplement the function\n\n```haskell\nstringOfList :: (a -\u003e String) -\u003e [a] -\u003e String\n```\n\nsuch that `stringOfList f [x1,...,xn]` should return the string\n`\"[\" ++ (f x1) ++ \", \" ++ ... ++ (f xn) ++ \"]\"`\n\nThis function can be implemented on one line,\n**without using any recursion** by calling\n`map` and `sepConcat` with appropriate inputs.\n\nYou should get the following behavior:\n\n```haskell\nghci\u003e stringOfList show [1, 2, 3, 4, 5, 6]\n\"[1, 2, 3, 4, 5, 6]\"\n\nghci\u003e stringOfList (fun x -\u003e x) [\"foo\"]\n\"[foo]\"\n\nghci\u003e stringOfList (stringOfList show) [[1, 2, 3], [4, 5], [6], []]\n\"[[1, 2, 3], [4, 5], [6], []]\"\n```\n\n## Problem 4: Big Numbers\n\nThe Haskell type `Int` only contains values up to a certain size (for reasons\nthat will become clear as we implement our own compiler). For example,\n\n```haskell\nghci\u003e let x = 99999999999999999999999999999999999999999999999 :: Int\n\n\u003cinteractive\u003e:3:9: Warning:\n    Literal 99999999999999999999999999999999999999999999999 is out of the Int range -9223372036854775808..9223372036854775807\n```\n\nYou will now implement functions to manipulate arbitrarily large\nnumbers represented as `[Int]`, i.e. lists of `Int`.\n\n### (a) 10 + 5 + 10 points\n\nWrite a function\n\n```haskell\nclone :: a -\u003e Int -\u003e [a]\n```\n\nsuch that `clone x n` returns a list of `n` copies of the value `x`.\nIf the integer `n` is `0` or negative, then `clone` should return\nthe empty list. You should get the following behavior:\n\n```haskell\nghci\u003e clone 3 5\n[3, 3, 3, 3, 3]\n\nghci\u003e clone \"foo\" 2\n[\"foo\", \"foo\"]\n```\n\nUse `clone` to write a function\n\n```haskell\npadZero :: [Int] -\u003e [Int] -\u003e ([Int], [Int])\n```\n\nwhich takes two lists: `[x1,...,xn]` `[y1,...,ym]` and\nadds zeros in front of the _shorter_ list to make the\nlists equal.\n\nYour implementation should *not** be recursive.\n\nYou should get the following behavior:\n\n```haskell\nghci\u003e padZero [9, 9] [1, 0, 0, 2]\n([0, 0, 9, 9], [1, 0, 0, 2])\n\nghci\u003e padZero [1, 0, 0, 2] [9, 9]\n([1, 0, 0, 2], [0, 0, 9, 9])\n```\n\nNext, write a function\n\n```haskell\nremoveZero :: [Int] -\u003e [Int]\n```\n\nthat takes a list and removes a prefix of leading zeros, yielding\nthe following behavior:\n\n```haskell\nghci\u003e removeZero [0, 0, 0, 1, 0, 0, 2]\n[1, 0, 0, 2]\n\nghci\u003e removeZero [9, 9]\n[9, 9]\n\nghci\u003e removeZero [0, 0, 0, 0]\n[]\n```\n\n### (b) 25 points\n\nLet us use the list `[d1, d2, ..., dn]`, where each `di`\nis between `0` and `9`, to represent the (positive)\n**big-integer** `d1d2...dn`.\n\n```haskell\ntype BigInt = [Int]\n```\n\nFor example, `[9, 9, 9, 9, 9, 9, 9, 9, 9, 8]` represents\nthe big-integer `9999999998`. Fill out the implementation for\n\n```haskell\nbigAdd :: BigInt -\u003e BigInt -\u003e BigInt\n```\n\nso that it takes two integer lists, where each integer is\nbetween `0` and `9` and returns the list corresponding to\nthe addition of the two big-integers. Again, you have to\nfill in the implementation to supply the appropriate values\nto `f`, `base`, `args`. You should get the following behavior:\n\n```haskell\nghci\u003e bigAdd [9, 9] [1, 0, 0, 2]\n[1, 1, 0, 1]\n\nghci\u003e bigAdd [9, 9, 9, 9] [9, 9, 9]\n[1, 0, 9, 9, 8]\n```\n\n### (c) 15 + 20 points\n\nNext you will write functions to multiply two big integers.\nFirst write a function\n\n```haskell\nmulByDigit :: Int -\u003e BigInt -\u003e BigInt\n```\n\nwhich takes an integer digit and a big integer, and returns the\nbig integer list which is the result of multiplying the big\ninteger with the digit. You should get the following behavior:\n\n```haskell\nghci\u003e mulByDigit 9 [9,9,9,9]\n[8,9,9,9,1]\n```\n\nNow, using `mulByDigit`, fill in the implementation of\n\n```haskell\nbigMul :: BigInt -\u003e BigInt -\u003e BigInt\n```\n\nAgain, you have to fill in implementations for `f` , `base` , `args` only.\nOnce you are done, you should get the following behavior at the prompt:\n\n```haskell\nghci\u003e bigMul [9,9,9,9] [9,9,9,9]\n[9,9,9,8,0,0,0,1]\n\nghci\u003e bigMul [9,9,9,9,9] [9,9,9,9,9]\n[9,9,9,9,8,0,0,0,0,1]\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplsyssec%2F00-warmup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplsyssec%2F00-warmup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplsyssec%2F00-warmup/lists"}