19
\$\begingroup\$

The Dutch system for naming one's ancestors is a lot more interesting than the English version. For English, the sequence goes "parent", "grandparent", "great-grandparent", "great-great-grandparent", "great-great-great-grandparent"; and in Dutch those terms are "ouder", "grootouder", "overgrootouder", "betovergrootouder", "stamouder". And so it continues with a non-positional mixed-radix counting system that produces unique names for up to 513 generations.

To not make this a mere string compression challenge, you can use the initials for each keyword. The pattern is like this:

Generation Full Dutch name Initialism (return this) Note
1 proband Return nothing (whitespace allowed)
2 ouder O
3 grootouder GO
4 overgrootouder OGO
5 betovergrootouder BOGO
6 oudouder OO 2 with prefix "oud"
7 oudgrootouder OGO 3 with prefix "oud"
8 oudovergrootouder OOGO 4 with prefix "oud"
9 oudbetovergrootouder OBOGO 5 with prefix "oud"
10 to 17 stamouder to stamoudbetovergrootouder SO to SOBOGO 2 to 9 with prefix "stam"
18 to 33 edelouder to edelstamoudbetovergrootouder EO to ESOBOGO 2 to 17 with prefix "edel"
34 to 65 voorouder to vooredelstamoudbetovergrootouder VO to VESOBOGO 2 to 33 with prefix "voor"
66 to 129 aartsouder to aartsvooredelstamoudbetovergrootouder AO to AVESOBOGO 2 to 65 with prefix "aarts"
130 to 257 opperouder to opperaartsvooredelstamoudbetovergrootouder OO to OAVESOBOGO 2 to 129 with prefix "opper"
258 to 513 hoogouder to hoogopperaartsvooredelstambetovergrootouder HO to HOAVESOBOGO 2 to 257 with prefix "hoog"

Challenge

Take a number between 1 and 513 inclusive. Return the appropriate abbreviated Dutch ancestor term; case doesn't matter. It's , the shortest code wins!

Test cases

input;output
1;
2;O
4;OGO
6;OO
9;OBOGO
267;HSGO
513;HOAVESOBOGO
\$\endgroup\$
9
  • 1
    \$\begingroup\$ Is it correct that 6 and 130 have the same acronym? \$\endgroup\$
    – mousetail
    Dec 28, 2023 at 14:11
  • 3
    \$\begingroup\$ @TheEmptyStringPhotographer Statistically, he lived around 9000 BC :) \$\endgroup\$
    – KeizerHarm
    Dec 28, 2023 at 14:53
  • 2
    \$\begingroup\$ May I have the input 0-indexed, so that I'm in my generation, my parents are 1 generation prior to me, my grandparents are 2 generations prior, etc? \$\endgroup\$
    – Neil
    Dec 28, 2023 at 15:15
  • 2
    \$\begingroup\$ @Neil Sorry but that would make it too easy ^^; (Dutch) genealogists count from 1, one's own generation. \$\endgroup\$
    – KeizerHarm
    Dec 28, 2023 at 15:52
  • 2
    \$\begingroup\$ @NickKennedy whitespace is fine \$\endgroup\$
    – KeizerHarm
    Dec 28, 2023 at 21:09

11 Answers 11

7
\$\begingroup\$

Jelly, 29 bytes

7ŒPUṢị“OSEVAOH”p“OGOB”UƤ¤⁶;ị@

A full program taking an integer argument and outputting a string to STDOUT. When called as a link, will produce a list of two strings (other than for 1); these are implicitly concatenated when run as a full program.

Explanation

7ŒP                            | Power set of 1..7
   U                           | Reverse each list
    Ṣ                          | Sort
     ị“OSEVAOH”                | Index into "OSEVAOH"
               p“OGOB”UƤ¤      | Cartesian product with reversed prefixes of "OGOB"
                         ⁶;    | Prefix with space, to handle the proband case
                           ị@  | Index the original link argument into this
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Oh, good call with 7ŒP! I tried something like this, but only used ŒP on the string directly and gave up once I realized it was out of order. \$\endgroup\$ Dec 29, 2023 at 1:11
5
\$\begingroup\$

Python, 72 bytes

f=lambda i:i>5and"OSEVAOH"[m:=len(bin(i-2))-5]+f(i-(4<<m))or"BOGO"[5-i:]

Attempt This Online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Why not just i>5 but i//6? \$\endgroup\$
    – l4m2
    Dec 28, 2023 at 21:50
3
\$\begingroup\$

Jelly, 33 bytes

_2d4+Ø.Ub"ؽU“OGOB“OSEVAOH”x"FUḣ’

Try it online!

This is... not good...

\$\endgroup\$
3
\$\begingroup\$

Charcoal, 32 bytes

¿⊖θ«⮌ΦOSEVAOH&⁴÷⁻θ²X²κ✂BOGO﹪⁻¹θ⁴

Try it online! Link is to verbose version of code. Explanation:

¿⊖θ«

Do nothing if the input is 1.

⮌ΦOSEVAOH&⁴÷⁻θ²X²κ

Work out which prefixes to output according to the binary representation of (n-2)//4.

✂BOGO﹪⁻¹θ⁴

Work out how much of betovergrootouder to output.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ It's always surprising to me when I look at Charcoal or Jelly answer and actually recognise stuff from the question :) Is 7 characters around the point where string compression costs more characters than it solves? \$\endgroup\$
    – KeizerHarm
    Dec 28, 2023 at 18:01
  • 1
    \$\begingroup\$ @KeizerHarm I don't know an easy way to tell how much the strings would be compressed, but there's a two byte penalty for having a compressed string which doesn't help. \$\endgroup\$
    – Neil
    Dec 28, 2023 at 18:26
  • 1
    \$\begingroup\$ @KeizerHarm I double-checked and OSEVAOH "compresses" to ”$‽üSY5” so the two byte penalty is what's killing it here. \$\endgroup\$
    – Neil
    Dec 29, 2023 at 1:08
  • 1
    \$\begingroup\$ @KeizerHarm In the Jelly case, compressed strings don't cost any more than uncompressed (you just change the trailing quote), but the only compression algorithm is based on an English wordlist so it does poorly on relative gibberish: the shortest compressed string for OSEVAOH is ¤T×ṄıṀė, which ties in length. \$\endgroup\$ Dec 29, 2023 at 2:26
2
\$\begingroup\$

JavaScript (Node.js), 64 bytes

n=>[...'HOAVESOBOGO'].filter(x=>i-->2?n>0&n>>i:n%4>i+1,i=9,n-=2)

Try it online!

Returns array

JavaScript (Node.js), 75 bytes

f=(n,i=7)=>i--?n-1>4<<i?'OSEVAOH'[i]+f(n-(4<<i),i):f(n,i):'BOGO '.slice(-n)

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Haskell, 78 bytes

g n|n<6=drop(5-n)"BOGO"
g n=[p:g(n-2^s)|(p,s)<-zip"HOAVESO"[8,7..],2^s+1<n]!!0

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Scala 3, 121 bytes

A port of @mousetail's Python answer in Scala.


def f(i:Int):String={if(i>5){val m=Integer.toBinaryString(i-2).size-3;"OSEVAOH"(m)+f(i-(4<<m))}else"BOGO".substring(5-i)}

Attempt This Online!

\$\endgroup\$
2
\$\begingroup\$

05AB1E, 30 29 bytes

.•1<P“Ï•6Ýæíè"ogob"ηíâ€S¯šI<è

Port of @NickKennedy's Jelly answer, so make sure to upvote that answer as well.

Output as a list of lowercase characters.

Try it online or verify all test cases.

A port of @Neil's Charcoal answer would be 1 byte longer:

≠.•1<P“Ï•IÍ4÷bRÏR.•ÇF•$-4%.$«×

Outputs as a lowercase string.

Try it online or verify all test cases.

Explanation:

        6Ý       # Push list [0,1,2,3,4,5,6]
          æ      # Pop and push the powerset of this
           í     # Reverse each inner list
.•1<P“Ï•    è    # Index each inner value into compressed string "osevaoh"
"ogob"           # Push this string
      η          # Pop and push its prefixes
       í         # Reverse each prefix
â                # Cartesian power of the two lists to get all possible pairs
 €               # Map over each pair:
  S              #  Convert the pair of strings to a flattened list of characters
   ¯š            # Prepend an empty list
     I           # Push the input
      <          # Decrease it by 1 to make it 0-based
       è         # Index it into the list of lists of characters
                 # (after which it is output implicitly)
≠                # Check if the (implicit) input is NOT 1
                 # (0 if input=1, 1 otherwise
.•1<P“Ï•         # Push compressed string "osevaoh"
        IÍ       # Push the input, and decrease it by 2
          4÷     # Integer-divide it by 4
            b    # Convert it to a binary string
             R   # Revert it
              Ï  # Keep the characters in "osevaoh" at the truthy bits
               R # Reverse that string
.•ÇF•            # Push compressed string "bogo"
     $           # Push 1 and the input
      -          # Subtract the input from the 1
       4%        # Modulo 4
         .$      # Remove that many leading characters from "bogo"
«                # Append the two substrings together
×                # Repeat this string the input==1 check amount of times
                 # (so input=1 becomes an empty string)
                 # (which is output implicitly as result)

See this 05AB1E tip of mine (section How to compress strings not part of the dictionary?) to understand why .•1<P“Ï• is "osevaoh" and .•ÇF• is "bogo" (Minor note: "ogob" and .•4ā:• are the same length, so no use compressing it.)

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I said that case doesn't matter, you don't actually need to uppercase it :) \$\endgroup\$
    – KeizerHarm
    Jan 5 at 9:28
  • 2
    \$\begingroup\$ @KeizerHarm Ah, I read past that, thanks for mentioning. Leuke challenge btw! Ik wist niet dat er benamingen tot 513 generaties terug waren. TIL. :) \$\endgroup\$ Jan 5 at 10:01
1
\$\begingroup\$

Retina 0.8.2, 85 70 bytes

.+
$*G
G$

G$
O
G{8}
S
GGGG
O
SS
E
EE
V
VV
A
AAAA
H
AA
O
GGG
BOG
GG
OG

Try it online! Link includes test cases. Explanation:

.+
$*G
G$

G$
O

Convert to unary using Gs, subtract 1 to correct for the input being 1-indexed, then replace any last G with O, so it doesn't accidentally get converted below.

G{8}
S
GGGG
O
SS
E
EE
V
VV
A
AAAA
H
AA
O

Handle the HOAVESO prefixes, starting with S and working back to H, then finish with the Os (because 134 should become OOO and not OS or HO). Edit: Saved 15 bytes thanks to @Ausername.

GGG
BOG
GG
OG

Fix up any remaining multiple Gs.

I tried this in Retina 1 but unfortunately cyclic transliteration just crashes out if the input is empty which is a shame as that's a legal output.

132 bytes to translate into Dutch: Try it online! Link includes test cases. Note: Based on my previous 85-byte solution.

\$\endgroup\$
5
  • \$\begingroup\$ I don't know Retina, but would doing GGGG -> O, OO -> S, SS -> E etc work to save a few bytes ? \$\endgroup\$
    – emanresu A
    Dec 28, 2023 at 17:49
  • \$\begingroup\$ @emanresuA OO to S doesn't work, but I came up with something that does. \$\endgroup\$
    – Neil
    Dec 28, 2023 at 18:50
  • \$\begingroup\$ Because unary input is allowed by default, you can -3 bytes by converting 1 to G instead of decimal to unary. \$\endgroup\$
    – TwiNight
    Dec 29, 2023 at 7:30
  • \$\begingroup\$ Appreciate the full Dutch answer :) I like that it translates higher numbers than 513 by just adding more instances of "hoog" - will submit that to the genealogists! :D \$\endgroup\$
    – KeizerHarm
    Dec 30, 2023 at 21:43
  • \$\begingroup\$ @KeizerHarm I think that if they find records of ancestors that far back they'll be able to add whatever prefix they want. \$\endgroup\$
    – Neil
    Dec 30, 2023 at 22:11
1
\$\begingroup\$

Retina, 54 bytes

11$
O
1(1)(?<1>\1\1)+
$#1
Y^`11d`G\O_B\OS\E\VA\O\H
G$

Attempt This Online!

Input in unary

Explanation

So, given input \$n\$, this challenge is mostly to convert \$n-2\$ to binary.


11$
O

Replace the last two 1s with an O. So we have \$n-2\$ (in unary) followed by O. (There will be a special case for input 1)


1(1)(?<1>\1\1)+
$#1

The regex matches any power of 2 that is ≥ 4, then we replace those with their log2.

This results in a list of digits 8~2 corresponding to the binary representation of \$n-2\$, followed by 0~3 1s representing the remainder of \$(n-2) \div 4\$ , followed by O.

For example if \$n = 269\$ (i.e. \$n-2 = 267 = 100001011_2 = 2^8 + 2^3 + 3\$), the result is 83111O


Y^`11d`G\O_B\OS\E\VA\O\H

From right to left, process each character as follows:

Character Output
First occurrence of 1 G
Second occurrence of 1 O
0 (won't happen, but removing this mapping costs 1 byte so...) Remove
Third occurrence of 1 B
2 O
3 S
4 E
5 V
6 A
7 O
8 H
Other Unchanged

G$

The only thing left to do is to deal with \$n=1\$, which end up as a single G. Since any other valid input ends with an O, we can special case \$n=1\$ by "removing the last character if it is G"

\$\endgroup\$
1
\$\begingroup\$

Perl 5 -p, 93 bytes

say+(map{(O,S,E,V,A,O,H)[--$i]x$_}(sprintf"%07b",$_/4)=~/./g),substr BOGO,3-($_&3)if($_-=2)+1

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.