10
\$\begingroup\$

Introduction

In this challenge, your task is to correctly list the cases of two Finnish nouns. The twist is that you may use one of the listings as a guide to produce the other.

The Nouns

We use the following two declination tables as our data. They list the cases of two nouns, one case per line in the same order as in the Wikipedia article linked above, in the form singular : plural where applicable.

Table 1: Cases of ovi ("door")

ovi : ovet
oven : ovien
oven : ovet
ovea : ovia
ovessa : ovissa
ovesta : ovista
oveen : oviin
ovella : ovilla
ovelta : ovilta
ovelle : oville
ovena : ovina
oveksi : oviksi
ovin
ovetta : ovitta
ovine

Table 2: Cases of jalka ("foot")

jalka : jalat
jalan : jalkojen
jalan : jalat
jalkaa : jalkoja
jalassa : jaloissa
jalasta : jaloista
jalkaan : jalkoihin
jalalla : jaloilla
jalalta : jaloilta
jalalle : jaloille
jalkana : jalkoina
jalaksi : jaloiksi
jaloin
jalatta : jaloitta
jalkoine

The Task

Your task is to write two programs f and g (possibly with different names) that take one string as input, give one string as output, and have the following property. If Table 1 is given to f as input, it outputs Table 2, and if Table 2 is given to g, it outputs Table 1. All other inputs result in undefined behavior. The tables must appear exactly as above in both input and output. You may optionally assume that there is a trailing newline, but then it must be used in both tables, and in both input and output. There is no preceding newline.

Rules and Bonuses

You can write f and g as either functions or full programs, but they must be of the same type, and they must be completely separate (if you write a helper function for f, you must re-write it in g if you want to use it there). The lowest total byte count wins, and standard loopholes are disallowed.

There is a bonus of -25 % for not using regular expressions.

Some Clarifications

It is perfectly fine to write a function/program f that ignores its input and always returns Table 2, and a function/program g that always returns Table 1. It is only required that f(Table 1) == Table 2 and g(Table 2) == Table 1; the behavior of f and g on all other inputs is irrelevant.

The "completely separate" part means the following. Your answer provides two pieces of code, one for f and one for g, preferably in different code boxes. If I put the code for f in a file and run it, it works, and the same for g. Your score is the sum of the byte counts of the two pieces of code. Any duplicated code is counted twice.

\$\endgroup\$
  • \$\begingroup\$ if Table 1 is given `f` as input How does one input a function into a table? I don't understand this part \$\endgroup\$ – user34736 Feb 24 '15 at 16:15
  • \$\begingroup\$ @Reticality "If Table 1 is given to f as input" \$\endgroup\$ – Zgarb Feb 24 '15 at 16:34
5
\$\begingroup\$

Perl, 105 + 54 = 159

Program f (try me):

#!perl -p
s/vi /vka /;s/ve/va/g;s/en/an/;s/vi/voi/;s/ov/1&34960>>$.?jalk:jal/eg;s/ii/ihi/;s/loia/lkoje/;s/oia/oja/

Program g (try me):

#!perl -p
s/jalk?o?/ov/g;s/va /vi /;s/va/ve/g;s/an/en/;y/jh/i/d

An alternative version of f, only 2 bytes longer (this method can be also applied to g but it would be too long):

#!perl -p0
ka1a1a1koj1a1a1ka1koj1a1o0a1o0kaa2koih1a1o0a1o0a1o0ka1ko0a1o0o0a1o0ko=~s!\D+!"s/ov".'.'x$'."/jal$&/"!gree

Technically this still uses a regexp (to decode the substitution string and then to apply them) so I cannot claim the bonus here.

\$\endgroup\$
  • \$\begingroup\$ Wow, good work with s/jalk?o?/ov/g! That one's powerful. \$\endgroup\$ – Sp3000 Feb 25 '15 at 11:05
4
\$\begingroup\$

Perl, 131 + 74 = 205

Table 1 to Table 2

$_=join"",<>;s/ee/kaa/;s/ii/koihi/;s/i(e|a)/koj$1/g;s/i(na|ne)/koi$1/g;s/v[ie](.?a| )/vka$1/g;s/vi/voi/g;s/ve/va/g;s/ov/jal/g;print

Expanded:

$_=join"",<>;
s/ee/kaa/;
s/ii/koihi/;
s/i(e|a)/koj$1/g;
s/i(na|ne)/koi$1/g;
s/v[ie](.?a| )/vka$1/g;
s/vi/voi/g;
s/ve/va/g;
s/ov/jal/g;
print

Table 2 to Table 1

$_=join"",<>;s/aan/aen/;s/jal(ka\b|oi|ko[ij]h?)/ovi/g;s/jalk?a/ove/g;print

Expanded:

$_=join"",<>;
s/aan/aen/;
s/jal(ka\b|oi|ko[ij]h?)/ovi/g;
s/jalk?a/ove/g;
print

(Thanks to @nutki for some Perl tips)

Despite the penalty on regexes, I decided to tackle it anyway and learn Perl while I was at it. I'm assuming there's some Perl tricks which might let me chain replacements, but I couldn't find any in my quick search online.

It's much harder to go from the ovi table to jalka table, which I'm guessing is because the jalka table has additional nuances to make words easier to pronounce.


Here's the replacement table I was working off:

i <-> ka
--------
ov i               jal ka

e <-> ka
--------
ov e a             jal ka a
ov e na            jal ka na

e <-> a
-------
ov e t             jal a t
ov e n             jal a n
ov e ssa           jal a ssa
ov e sta           jal a sta
ov e lla           jal a lla
ov e lta           jal a lta
ov e lle           jal a lle
ov e ksi           jal a ksi
ov e tta           jal a tta

i <-> oi
--------
ov i ssa           jal oi ssa
ov i sta           jal oi sta
ov i lla           jal oi lla
ov i lta           jal oi lta
ov i lle           jal oi lle
ov i ksi           jal oi ksi
ov i n             jal oi n
ov i tta           jal oi tta

i <-> koi
---------
ov i na            jal koi na
ov i ne            jal koi ne

i <-> koj
---------
ov i en            jal koj en
ov i a             jal koj a

i <-> koih
------------
ov i in            jal koih in

ee <-> kaa
----------
ov ee n            jal kaa n
\$\endgroup\$
2
\$\begingroup\$

Python 2, 371 - 25% = 278

When table 1 is the input to function f, it returns table 2. If the input is not table 1, it's output is undefined (however likely but not guaranteed to return table 2). For example, calling f(9**9**9**9) will probably not return table 2.

f=lambda a:'jalkaBatAanBkojenAanBatAkaaBkojaAassaBoissaAastaBoistaAkaanBkoihinAallaBoillaAaltaBoiltaAalleBoilleAkanaBkoinaAaksiBoiksiAoinAattaBoittaAkoine'.replace('A','\njal').replace('B',' : jal')

The same logic is used with function g:

g=lambda a:'oviBetAenBienAenBetAeaBiaAessaBissaAestaBistaAeenBiinAellaBillaAeltaBiltaAelleBilleAenaBinaAeksiBiksiAinAettaBittaAine'.replace('A','\nov').replace('B',' : ov')

The functions are independent.

\$\endgroup\$
0
\$\begingroup\$

Python - 462 - 25% = 346.5

This program does the obvious, direct approach except for a few data golfing tricks. For the undefined behavior it print the table just like the defined behavior. What an amazing "coincidence"! :)

x,y="""ovi:ovet
oven:ovien
oven:ovet
ovea:ovia
ovessa:ovissa
ovesta:ovista
oveen:oviin
ovella:ovilla
ovelta:ovilta
ovelle:oville
ovena:ovina
oveksi:oviksi
ovin
ovetta:ovitta
ovineXjalka:jalat
jalan:jalkojen
jalan:jalat
jalkaa:jalkoja
jalassa:jaloissa
jalasta:jaloista
jalkaan:jalkoihin
jalalla:jaloilla
jalalta:jaloilta
jalalle:jaloille
jalkana:jalkoina
jalaksi:jaloiksi
jaloin
jalatta:jaloitta
jalkoine""".replace(':',' : ').split('X')
f=lambda n:y
g=lambda n:x

Now, if one would consider this cheating (yeah right), I can follow the spirit of the rules for 20 more characters = 482 - 25%=361.5. Just replace the last two lines with:

f=lambda n:[x,y][n==x]
g=lambda n:[y,x][n==y]

This would make the undefined behavior return not the correct table but the input table.

\$\endgroup\$
  • \$\begingroup\$ It's perfectly fine to always return the same table. However, the challenge states that all code used to define the functions must be separate (this may have been a little ambiguous, I'll try to clarify it). In particular, you can't define x and y in one expression, and use one in f and the other in y. \$\endgroup\$ – Zgarb Feb 25 '15 at 8:50
  • \$\begingroup\$ "in y" -> "in g" \$\endgroup\$ – Zgarb Feb 25 '15 at 9:03
0
\$\begingroup\$

VBA 1204 (1605 - 25%) 1191 (1587 - 25%)

The direct approach.

Edit: Corrected bug and used replace trick from @Maltysen

Function f(s)
    If Replace(s, " : ", ":") = "ovi:ovet" & vbLf & "oven:ovien" & vbLf & "oven:ovet" & vbLf & "ovea:ovia" & vbLf & "ovessa:ovissa" & vbLf & "ovesta:ovista" & vbLf & "oveen:oviin" & vbLf & "ovella:ovilla" & vbLf & "ovelta:ovilta" & vbLf & "ovelle:oville" & vbLf & "ovena:ovina" & vbLf & "oveksi:oviksi" & vbLf & "ovin" & vbLf & "ovetta:ovitta" & vbLf & "ovine" Then f = Replace("jalka:jalat" & vbLf & "jalan:jalkojen" & vbLf & "jalan:jalat" & vbLf & "jalkaa:jalkoja" & vbLf & "jalassa:jaloissa" & vbLf & "jalasta:jaloista" & vbLf & "jalkaan:jalkoihin" & vbLf & "jalalla:jaloilla" & vbLf & "jalalta:jaloilta" & vbLf & "jalalle:jaloille" & vbLf & "jalkana:jalkoina" & vbLf & "jalaksi:jaloiksi" & vbLf & "jaloin" & vbLf & "jalatta:jaloitta" & vbLf & "jalkoine", ":", " : ")
End Function

Function g(s)
    If Replace(s, " : ", ":") = "jalka:jalat" & vbLf & "jalan:jalkojen" & vbLf & "jalan:jalat" & vbLf & "jalkaa:jalkoja" & vbLf & "jalassa:jaloissa" & vbLf & "jalasta:jaloista" & vbLf & "jalkaan:jalkoihin" & vbLf & "jalalla:jaloilla" & vbLf & "jalalta:jaloilta" & vbLf & "jalalle:jaloille" & vbLf & "jalkana:jalkoina" & vbLf & "jalaksi:jaloiksi" & vbLf & "jaloin" & vbLf & "jalatta:jaloitta" & vbLf & "jalkoine" Then f = Replace("ovi:ovet" & vbLf & "oven:ovien" & vbLf & "oven:ovet" & vbLf & "ovea:ovia" & vbLf & "ovessa:ovissa" & vbLf & "ovesta:ovista" & vbLf & "oveen:oviin" & vbLf & "ovella:ovilla" & vbLf & "ovelta:ovilta" & vbLf & "ovelle:oville" & vbLf & "ovena:ovina" & vbLf & "oveksi:oviksi" & vbLf & "ovin" & vbLf & "ovetta:ovitta" & vbLf & "ovine", ":", " : ")
End Function

Run from the Immediate window:

msgbox f("ovi : ovet" & vbLf & "oven : ovien" & vbLf & "oven : ovet" & vbLf & "ovea : ovia" & vbLf & "ovessa : ovissa" & vbLf & "ovesta : ovista" & vbLf & "oveen : oviin" & vbLf & "ovella : ovilla" & vbLf & "ovelta : ovilta" & vbLf & "ovelle : oville" & vbLf & "ovena : ovina" & vbLf & "oveksi : oviksi" & vbLf & "ovin" & vbLf & "ovetta : ovitta" & vbLf & "ovine")
\$\endgroup\$
  • \$\begingroup\$ Wouldn't you only have to check if the first character is 'o' or 'j' ? \$\endgroup\$ – Claudiu Feb 24 '15 at 22:06
  • \$\begingroup\$ @Claudiu Actually, there's no need to check anything; functions that ignore their input and always return the same table are valid answers. I'll clarify that in the challenge. \$\endgroup\$ – Zgarb Feb 25 '15 at 8:49
  • \$\begingroup\$ @Claudiu I thought about that, but what if someone ran it by passing "o"? \$\endgroup\$ – phrebh Feb 25 '15 at 14:11
  • \$\begingroup\$ @Zgarb It seems like you think my functions are ignoring their input, which they're not (technically). There's no translation of characters, though. \$\endgroup\$ – phrebh Feb 25 '15 at 14:12
  • \$\begingroup\$ No, I'm just saying that they could simply ignore their inputs and still be valid. \$\endgroup\$ – Zgarb Feb 25 '15 at 14:17
0
\$\begingroup\$

JavaScript (ES6) 271 (165 + 196 -25%)

Starting simple. The functions ignore input parameter at all.
Using split/join instead of replace to avoid regular expressions.

g=_=>'ovi1et0n1ien0n1et0a1ia0ssa1issa0sta1ista0en1iin0lla1illa0lta1ilta0lle1ille0na1ina0ksi1iksi\novin0tta1itta\novine'
.split(0).join('\nove').split(1).join(' : ov')
f=_=>'jalka1at0an1kojen0an1at0kaa1koja0assa1oissa0asta1oista0kaan1koihin0alla1oilla0alta1oilta0alle1oille0kana1koina0aksi1oiksi0oin0atta1oitta0koine'
.split(0).join('\njal').split(1).join(' : jal')

Test in Firefox/FireBug console

console.log(f('ovi : ovet\noven : ovien\noven : ovet\novea : ovia\novessa : ovissa\novesta : ovista\noveen : oviin\novella : ovilla\novelta : ovilta\novelle : oville\novena : ovina\noveksi : oviksi\novin\novetta : ovitta\novine'))

jalka : jalat
jalan : jalkojen
jalan : jalat
jalkaa : jalkoja
jalassa : jaloissa
jalasta : jaloista
jalkaan : jalkoihin
jalalla : jaloilla
jalalta : jaloilta
jalalle : jaloille
jalkana : jalkoina
jalaksi : jaloiksi
jaloin
jalatta : jaloitta
jalkoine

console.log(g("jalka : jalat\njalan : jalkojen\njalan : jalat\njalkaa : jalkoja\njalassa : jaloissa\njalasta : jaloista\njalkaan : jalkoihin\njalalla : jaloilla\njalalta : jaloilta\njalalle : jaloille\njalkana : jalkoina\njalaksi : jaloiksi\njaloin\njalatta : jaloitta\njalkoine"))

ovi : ovet
oven : ovien
oven : ovet
ovea : ovia
ovessa : ovissa
ovesta : ovista
oveen : oviin
ovella : ovilla
ovelta : ovilta
ovelle : oville
ovena : ovina
oveksi : oviksi
ovin
ovetta : ovitta
ovine

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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