[48in24 Exercise] [04-30] All Your Base

This issue is a discussion for contributors to collaborate in getting ready to be featured in 48in24. Please refer to this forum topic for more info.


We will be featuring All Your Base from Apr 30 onwards.

Staff jobs

These are things for Erik/Jeremy to do:

  • :ballot_box_with_check: Check/update exercise in Problem Specifications
  • ☐ Create + schedule video

Community jobs

For each track:

  • Implement All Your Base
  • Add approaches (and an approaches introduction!) for each idiomatic or interesting/educational approach.
  • Add video walkthroughs (record yourself solving and digging deeper into the exercise).
  • Highlight up to 16 different featured exercises (coming soon)

Existing Approaches

You can use these as the basis for approaches on your own tracks. Feel free to copy/paste/reuse/rewrite/etc as you see fit! Maybe ask ChatGPT to translate to your programming language.

  • in-parallel (cpp)
  • in-sequence (cpp)

Track Statuses

You can see an overview of which tracks have implemented the exercise at the #48in24 implementation status page.

I’ve currently gathered the following solutions to feature:

  1. Elixir: function clauses, higher-order function and built-in base conversion
    Use clauses and higher-order function to validate input, built-in functions for base conversion

  2. Julia: use loops to first convert to base 10 then to convert to output base
    divrem gives remainder and division, latter being the digit

  3. Erlang: manual recursion and guard
    Use manual recursion and a guard

  4. Gleam: functional pipeline with error handling via Result and use
    Use Result type to indicate errors and use for syntactic sugar

  5. Go: arbitrary precision division
    Directly work on digits without converting to intermediate value

  6. R: vectorized operations
    Use vectorized operations

  7. Raku: polymod and infinite list
    Use polymod and infinite list

  8. Prolog: define relations between input and output
    Define the relation between the input and output base conversion and use bi-directional relations

  9. Prolog: use grammar for digits
    Define the relation between the input and output base conversion using a grammar and parsing

If anyone has more suggestions, do let us know!

I’ll port it for Ballerina, CoffeeScript, and D.

1 Like

My humble R solution, which vectorizes over ranges to convert, without any extra loops. (Just a suggestion)

1 Like

@Steffan153 Funnily enough, I had already your solution to my list, I just forgot to update the list in this topic.

My latest Go solution is a bit like C++ only much neater…
(it may take a moment of reflection to figure out how/why no digit of inputDigits ever ends up >= inputBase)

Some C# 12 syntactic sugar?

That link doesn’t work for me, I assume it should have been this:
c# 12 syntactic sugar

Ah, thanks. My link had double parentheses…

A long method chain in Raku. It uses array indexes on the digit elements followed by a sum to convert to base 10, then a recursive method call on the resulting base 10 number to convert to a list of digits for the expected base.

1 Like
method {
        when self ≥ %bases<to> {
            slip( self % %bases<to>, samewith(self div %bases<to>) );
        }
        default { self }

Could you explain what this code does in more detail?

Sure! FYI I changed the when/default to if/else as they’re functionally identical here and the latter is likely more familiar to most.

If we take 42 as an example, and convert to base 2, we start with:
if 42 ≥ 2. Since this is true, we get a list, with the first element of the list being 42 % 2 == 0. samewith is being used for self recursion, the method now being called on 42 div 2 == 21 (div being integer division). self is the object, i.e. the current integer we called the method on.

A slip is a list that flattens itself into an outer list. Without it, the recursion would give use nesting lists, e.g., with 42: (0,(1,(0,(1,(0,1))))).

If I were to rewrite it as a named subroutine, it could look like this:

sub foo ($x) {
    if $x ≥ %bases<to> {
        slip( $x % %bases<to>, foo($x div %bases<to>) );
    }
    else { $x }
}
1 Like

Perfect, thanks

@m-dango - I used .polymod with a lazy infinite list - two interesting Raku language features too IMHO. (see line 7)

1 Like

That’s really cool! FYI if you want an infinitely repeating sequence of the same digit, you can use %bases<to> xx ∞.

The polymod documentation even has an example of base conversion :slightly_smiling_face:

1 Like

@m-dango - I golfed the code even more by using the SIMD » operator instead of map

Port for x86-64 assembly:

1 Like