[Question]
  [
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", "*over*grootouder", "*bet*overgrootouder", "*stam*ouder". And so it [continues](https://www.nazatendevries.nl/Genealogie/Achtergronden/Namen%20van%20voorouders.html) 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 [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), the shortest code wins!
### Test cases
```
input;output
1;
2;O
4;OGO
6;OO
9;OBOGO
267;HSGO
513;HOAVESOBOGO
```
  
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 29 bytes
```
7ŒPUṢị“OSEVAOH”p“OGOB”UƤ¤⁶;ị@
```
* [Try it online!](https://tio.run/##y0rNyan8/9/86KSA0Ic7Fz3c3f2oYY5/sGuYo7/Ho4a5BSCeu78TkBl6bMmhJY8at1kD1Tj8///fyMwcAA "Jelly – Try It Online")
* [Test suite](https://tio.run/##y0rNyan8/9/86KSA0Ic7Fz3c3f2oYY5/sGuYo7/Ho4a5BSCeu78TkBl6bMmhJY8at1kD1Tj8twZKKOjaKQAlrA@3c5kaGh9uf9S0JvI/AA "Jelly – Try It Online")
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
```
[Answer]
# [Python](https://www.python.org), 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!](https://ato.pxeger.com/run?1=m72soLIkIz9vwYKlpSVpuhY3PdJscxJzk1ISFTKtMu1ME_NSlPyDXcMc_T2UonOtbHNS8zSSMvM0MnWNNDV1TWO104BMDRMbm1xNzfwiJSd_d3-laFPdTKtYqHmaaflFCpkKmXkKRYl56akahjpGBoaaVlwKQFBQlJlXopGpowA0RFMTogHmEAA)
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 33 bytes
```
_2d4+Ø.Ub"Ø½U“OGOB“OSEVAOH”x"FUḣ’
```
[Try it online!](https://tio.run/##y0rNyan8/z/eKMVE@/AMvdAkpcMzDu0NfdQwx9/d3wlEBbuGOfp7PGqYW6HkFvpwx@JHDTP/mxoaH25/1LQm8j8A "Jelly – Try It Online")
This is... not good...
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 32 bytes
```
¿⊖θ«⮌ΦOSEVAOH＆⁴÷⁻θ²Ｘ²κ✂BOGO﹪⁻¹θ⁴
```
[Try it online!](https://tio.run/##Ncw9C8IwFIXhWX9F6HQDcbAUHZxa6tdQUhTcS3LFizGhadoO4m@PpeiZz/OqR@OVa0yMdGdQovL4QhtQQ8s5ey8XtScb4IID@g7hQCagh0Re97dcnhLBCgojdZhbDZlgZxtKGkgjVGT7DlrBUi5Y7cZJpYI9@bzdv3s1pBCSQh7l1Kqc7o370bVg7USz@f6JMd1s42owXw "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
¿⊖θ«
```
Do nothing if the input is `1`.
```
⮌ΦOSEVAOH＆⁴÷⁻θ²Ｘ²κ
```
Work out which prefixes to output according to the binary representation of `(n-2)//4`.
```
✂BOGO﹪⁻¹θ⁴
```
Work out how much of betovergrootouder to output.
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 64 bytes
```
n=>[...'HOAVESOBOGO'].filter(x=>i-->2?n>0&n>>i:n%4>i+1,i=9,n-=2)
```
[Try it online!](https://tio.run/##Dcm9CsIwEADgp9E25AdT6qD1ThREtwyCiziUmshJuEhaxLePXb7le/fffhwyfSbN6elLgMKAd2NMdXGH2@nqju7sqocJFCef6x8gaY3NnnG1ZETa8qJFklYRbBRraEQJKddEYDui3dq2nZREYkg8puhNTK85VZgRovwB "JavaScript (Node.js) – Try It Online")
Returns array
# [JavaScript (Node.js)](https://nodejs.org), 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!](https://tio.run/##FcuxCsIwEADQX3HLHckVAhWhTVoURLcMgos4lJiUk5JII/5@pOuD955@U/Erf76U8ivUGi0kxfaAdmCiMZEeWmN4FO52vh/dVTz4KSMkgo1RMXZxG9iJk7u4nWjKwj4AJawxr8BW92z2uu2lZPQ5lbyEZskzsIrAiPUP "JavaScript (Node.js) – Try It Online")
[Answer]
# [Haskell](https://www.haskell.org/), 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!](https://tio.run/##XZBNa4NAEIbv/orJUoLiB9k1GlvcQwIhuXkI5CIWhFQrTbcSe5CS/25nxzasXpZnZt5n2dn3svt4u16HoQZ1V2ksL7ev1o585bBddsiYhX2Zty@1rXzx2jl3u/U6J/V/mpYds@15f8pYnnibICg8nLs8VcVisRoq4CCBMasCoSHTFGo6EK6pOXKkefdXxDQg3BiZZGyPxTMV/4aCOwBfQSoRl0s8kICTfWLgulCBrcCnkAvCeTjJzAnpgfupk0yccD1zYnr9eeJgyHTieOpwQQtsJw6GDIeHs31ENP6G6eiQ4Yhotk/EaZ@j6egQOdZn2Sgct7dGfcMTlOoCOdTQg5QY7vHCHlIfch4EeFFRWMMv "Haskell – Try It Online")
[Answer]
# [Scala 3](https://www.scala-lang.org/), 121 bytes
A port of [@mousetail's Python answer](https://codegolf.stackexchange.com/a/268820/110802) 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!](https://ato.pxeger.com/run?1=LU_BSsNAEL33K4Y97RA21NaCxERoUdSD5FD0UnrY1k0YSXZld6vEkC_x0ote_KL-jZukMwzDzHtvePP96_aykvO_DRPafEqr2faUmd2b2nt4kqShnQC8qgLqMHBpS5fA0lrZbNbeki63mMCzJg9ZYAYqwM_BF-Lq1PSiglPyqD0mIzlrKWxuFth-yArqLECqVDb2ZkVa2mZkcRIzjB19KTG_Zvn67mWZPzBeYxTEgl-maY3Yqcoptsrvcxa7w86NyoUg7M4Gbgc3hbHACVIBF-ANzKZTHF7q4z1ofKUDHAELGfV-EQe0m_R1vnU8jv0f)
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~30~~ 29 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
.•1<P“Ï•6Ýæíè"ogob"ηíâ€S¯šI<è
```
Port of [*@NickKennedy*'s Jelly answer](https://codegolf.stackexchange.com/a/268826/52210), so make sure to upvote that answer as well.
Output as a list of lowercase characters.
[Try it online](https://tio.run/##yy9OTMpM/f9f71HDIkObgEcNcw73A5lmh@ceXnZ47eEVSvnp@UlK57YD2YseNa0JPrT@6EJPm8Mr/v83MjMHAA) or [verify all test cases](https://tio.run/##yy9OTMpM/W9qaOzqZ6@k8KhtkoKSvd9/vUcNiwxtAh41zDncD2SaHZ57eNnhtYdXKOWn5ycpndsOZC961LQm@ND6owv9bA6v@K/zHwA).
A port of [*@Neil*'s Charcoal answer](https://codegolf.stackexchange.com/a/268822/52210) would be 1 byte longer:
```
≠.•1<P“Ï•IÍ4÷bRÏR.•ÇF•$-4%.$«×
```
Outputs as a lowercase string.
[Try it online](https://tio.run/##yy9OTMpM/f//UecCvUcNiwxtAh41zDncD2R6Hu41Obw9KehwfxBI5nC7G5BU0TVR1VM5tPrw9P//jczMAQ) or [verify all test cases](https://tio.run/##yy9OTMpM/W9qaOzqZ6@k8KhtkoKSvd//R50L9B41LDK0CXjUMOdwP5Dpd7jX5PD2pKDD/UEgmcPtbiB5P10TVT2VQ6sPT/@v8x8A).
**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?*)](https://codegolf.stackexchange.com/a/166851/52210) 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.)
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), ~~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!](https://tio.run/##FYs7CoAwFAT7OUcEURD8a6kQnl2KQGotLGwsxE48e3wOLMvC7LXfx7nFJJU1FjkmE8TwxyHP8OIRRZf3WKwlEAITk8Ki9YsqzE6f6kmMJRUNHSNV19OW9Qc "Retina 0.8.2 – Try It Online") Link includes test cases. Explanation:
```
.+
$*G
G$
G$
O
```
Convert to unary using `G`s, 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 `O`s (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 `G`s.
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!](https://tio.run/##HcxRCsIwEATQ/zlHBVEQNm2jnsBbiCkJVdBu2cb@SM4eR2FZHrvDWMqPKdTN9nKrhz2aHa7SYDYdwhQhtL5jMsjH9b7grjrS4k4FOs//h@8KQrC80K0rWFV/Z2E8xfQkGV5yeFGMso@9giFlbo6uyQiMppprFTh08DjD@SN6ab8 "Retina 0.8.2 – Try It Online") Link includes test cases. Note: Based on my previous 85-byte solution.
[Answer]
# [Retina](https://github.com/m-ender/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!](https://ato.pxeger.com/run?1=m72sKLUkMy9xwTJVDS0N94SlpSVpuhY3zQwNVbj8uQw1DDU17G0M7WIMYww1tblUlA25IuMSDA1TEtxj_OOdYvyDY1xjwhxj_GM8uNxVuJYUJyUXb9B0T-DSAyrWM-CsUVDRNYKYueAWs4YhlyEIQQk4hcIaBaNhMdIBJMcAAA)
Input in unary
## Explanation
So, given input \$n\$, this challenge is mostly to convert \$n-2\$ to binary.
---
```
11$
O
```
Replace the last two `1`s 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 `1`s 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`"
[Answer]
# [Perl 5](https://www.perl.org/) `-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!](https://tio.run/##K0gtyjH9/784sVJbIzexoFrDXydYx1UnTMdRx1/HQzNaV1clM7ZCJb5Wo7igKDOvJE1J1cA8SUlHJV7fRNO2Tl9PP11Tp7g0qbikSMHJ391fx1hXQyVezVgzMw1I69oaaWob/v9v@S@/oCQzP6/4v66vqZ6BocF/3bwcAA "Perl 5 – Try It Online")
]