{"id":16688069,"url":"https://github.com/danielpclark/b64challenge","last_synced_at":"2025-07-18T07:02:06.663Z","repository":{"id":16635222,"uuid":"19390406","full_name":"danielpclark/b64challenge","owner":"danielpclark","description":"Golf Challenge Unique Base 64 Incrementor","archived":false,"fork":false,"pushed_at":"2014-05-10T21:19:18.000Z","size":196,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-20T12:46:25.741Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"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/danielpclark.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}},"created_at":"2014-05-02T22:28:23.000Z","updated_at":"2014-05-10T21:19:19.000Z","dependencies_parsed_at":"2022-08-17T16:10:51.094Z","dependency_job_id":null,"html_url":"https://github.com/danielpclark/b64challenge","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielpclark%2Fb64challenge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielpclark%2Fb64challenge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielpclark%2Fb64challenge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/danielpclark%2Fb64challenge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/danielpclark","download_url":"https://codeload.github.com/danielpclark/b64challenge/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243447642,"owners_count":20292455,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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-10-12T15:26:44.776Z","updated_at":"2025-03-13T17:27:33.537Z","avatar_url":"https://github.com/danielpclark.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Golf Challenge Unique Base 64 Incrementor\n\n**The goal is to write a script that will use your (Base 64) numbering system and never repeat any character within the string while incrementing.**\n\nWhen you rollover a big number that jumps to the next place value you need to substitute it with the next unique in place... example (in Base 10) 0985,0986,0987 jumps to 1023, 1024, 1025 to avoid repetition. Note: Rollovers are when you hit the top place value like 0999 and roll over to the next place value 1000\n\nSo increment all 12 character unique strings without wasting CPU cycles on skip loops.\n\n# **Rules**\n \n * No like characters within the 12 character string.\n * No skip/next command in loop from \"0985\",\"0986\",\"0987\" to \"1023\" (Base 10 example), use substitution.  This is a rollover.  Rollovers are no skip zones.\n * All down counts of any length (starting from the highest value character towards the next +11 characters) get substituted on rollover  Example: if Z was highest value character in the base and Y was next then YXWVUTSRQPON will roll over to Z0123456789a\n\n# **Criterion**\n\nPass 5 test cases with different position rollover cases (when the next place position increments).\n\n\u003e# **About Number Bases**\n\u003e\n\u003eOur numbering system is (Base 10).  That includes 0-9.  Binary is (Base 2), that's only \u003e1's and 0's.  Hex is (Base 16) (0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F).  A hexadecimal \"F\" has a \u003e(Base 10) value of 15.\n\u003e\n\u003eIn Binary, a string of two binary characters can have only two unique states.  Like '10' \u003eand '01'.  In this challenge Binary is not a possible choice since you can't have any more \u003eunique amount of characters then two since you only have 1 and 0.\n\u003e\n\u003e(Base 64) has 64 individual characters which would translate in value in (Base 10) from \u003ebetween 0 to 63.  See here for more on (Base 64) http://en.wikipedia.org/wiki/Base_64\n\n# **Logic Insights**\n\nYour incrementor function will increment to the next 'not in string' character on the right end until it gets to the highest character.  Once it get's to the last character then it passes on to the swap task.\n\nThe swap task then looks for the chunk to jump to eg: in (Base 10) to go from 00987 to the next level would be 01234. So seeing 00987 is the set to replace we have the 0 which \"can\" be incremented, and then the 987 which is a counting down sequence 9, 8, 7.  So we then increment the first number to the left so 0 turns to 1, and then substitute the 987 with the smallest unused numbers from left to right, which is 234.\n\n# Here is a working long answer written in Ruby:\n\n*The order of the (base 64) used in this code and output is as is defined on [Wikipedia][1]*\n\n\tclass B64\n\t\tdef initialize(string, lngth=12)\n\t\t\t@b64 = (\n\t\t\t\t(\"A\"..\"Z\").to_a + (\"a\"..\"z\").to_a + (\"0\"..\"9\").to_a + [\"+\",\"/\"]\n\t\t\t).each_with_index.map {|x,i| {x=\u003ei} }.inject(:update)\n\t\t\t@string = string\n\t\t\t@max = lngth.times.map { |i| @b64.invert[@b64.length-i-1] }.join(\"\")\n\t\t\t@start = lngth.times.map { |i| @b64.invert[i] }.join(\"\")\n\t\tend\n\n\t\tdef next\n\t\t\t# this is where everything moves forward\n\t\t\tunless inc(@string)\n\t\t\t\tswapper\n\t\t\tend\n\t\t\t@string\n\t\tend\n\n\t\tdef inc(s)\n\t\t\t# increment last item in string or false\n\t\t\tunless @b64[s[-1]] == @b64.length-1\n\t\t\t\tunless s == @max\n\t\t\t\t\tif first_non(s,s[-1])\n\t\t\t\t\t\ts[-1] = first_non(s,s[-1])\n\t\t\t\t\telsif not first_non(s,s[-2])\n\t\t\t\t\t\ts[-1] = first_non(s)\n\t\t\t\t\t\tif first_non(s,s[-2])\n\t\t\t\t\t\t\ts[-2] = first_non(s,s[-2])\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tswapper\n\t\t\t\t\t\tend\n\t\t\t\t\telse\n\t\t\t\t\t\tswapper\n\t\t\t\t\tend\n\t\t\t\telse\n\t\t\t\t\tswapper\n\t\t\t\tend\n\t\t\telse\n\t\t\t\treturn false\n\t\t\tend\n\t\t\treturn true\n\t\tend\n\n\t\tdef seek_high(s)\n\t\t\t# select with index highest number\n\t\t\tval = s.split(\"\").map { |x| @b64[x] }\n\t\t\treturn val.index(val.compact.max)\n\t\tend\n\n\t\tdef swapper\n\t\t\tif @string == @max\n\t\t\t\t@string = @start\n\t\t\telse\n\t\t\t\t# save loop cycles by substituting with next unique charcter set\n\t\t\t\tval = @string[0..seek_high(@string)-1]\n\t\t\t\tinc(val)\n\t\t\t\tcount = @string[seek_high(@string)..-1].length\n\t\t\t\tcount.times do\n\t\t\t\t\tval += first_non(val)\n\t\t\t\tend\n\t\t\t\t@string = val\n\t\t\tend\n\t\tend\n\n\t\tdef first_non(s,start = @b64.invert[0])\n\t\t\t# find the lowest not used character in base\n\t\t\t(@b64[start]..@b64.length-1).each do |p|\n\t\t\t\tunless !!s[@b64.invert[p]]\n\t\t\t\t\treturn @b64.invert[p]\n\t\t\t\tend\n\t\t\tend\n\t\t\treturn false\n\t\tend\n\tend\n\n\t# Pass 5 test cases with rollovers\n\t[\"ABCDEFGHIJK9\",\"ABCD/9876542\",\"ABCDEF+/9875\",\"ABCDEFG+/985\",\"A+/987654320\"].each do |val|\n\t\ttest = B64.new(val)\n\t\tputs \" ******** TEST FOR ROLLOVER SEQUENCE #{val} ******** \"\n\t\t5.times do\n\t\t\tprint test.next + \", \"\n\t\tend\n\t\tputs\n\t\tputs\n\tend\n\nAnd here is it's output.\n\n\t ******** TEST FOR ROLLOVER SEQUENCE ABCDEFGHIJK9 ******** \n\tABCDEFGHIJK+, ABCDEFGHIJK/, ABCDEFGHIJLK, ABCDEFGHIJLM, ABCDEFGHIJLN, \n\n\t ******** TEST FOR ROLLOVER SEQUENCE ABCD/9876542 ******** \n\tABCD/9876543, ABCD/987654+, ABCD/98765+E, ABCD/98765+F, ABCD/98765+G, \n\n\t ******** TEST FOR ROLLOVER SEQUENCE ABCDEF+/9875 ******** \n\tABCDEF+/9876, ABCDEF/GHIJK, ABCDEF/GHIJL, ABCDEF/GHIJM, ABCDEF/GHIJN, \n\n\t ******** TEST FOR ROLLOVER SEQUENCE ABCDEFG+/985 ******** \n\tABCDEFG+/986, ABCDEFG+/987, ABCDEFG/HIJK, ABCDEFG/HIJL, ABCDEFG/HIJM, \n\n\t ******** TEST FOR ROLLOVER SEQUENCE A+/987654320 ******** \n\tA+/987654321, A/BCDEFGHIJK, A/BCDEFGHIJL, A/BCDEFGHIJM, A/BCDEFGHIJN, \n\n\n# Submission\n\nPlease fork and send a pull request and name your file as follows `golfb64-\u003cyourname\u003e.xxx` for your golf answers and `longb64-\u003cyourname\u003e.xxx` for your long answer versions.  Use any promming language you'd like.  I've included my long version [`longb64-danielpclark.rb`][3]  To see other people's submissions you can check [here][2] as well.\n\n\n  [1]: http://en.wikipedia.org/wiki/Base_64\n  [2]: http://codegolf.stackexchange.com/questions/26503/base-64-all-unique-12-character-incrementor-without-skip-next-on-rollovers-in\n  [3]: https://github.com/danielpclark/b64challenge/blob/master/longb64-danielpclark.rb\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielpclark%2Fb64challenge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdanielpclark%2Fb64challenge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdanielpclark%2Fb64challenge/lists"}