¡Hola! For those of you who don't take Spanish, a verb is conjugated based on the person who does the action. Here's a chart:

English                   Spanish
I                         Yo
You                       Tú
He                        Él
She                       Ella
You (formal)              Usted
We all                    Nosotros
You all                   Vosotros
They (masculine, plural)  Ellos
They (feminine, plural)   Ellas
You (plural)              Ustedes

In Spanish, all verbs end with ar, er, or ir. Here's another helpful chart:

          Ar    Er    Ir
Yo        o     o     o
Tú        as    es    es
Él        a     e     e
Ella      a     e     e
Usted     a     e     e
Nosotros  amos emos imos
Vosotros  áis  éis  ís
Ellos     an   en   en
Ellas     an   en   en
Ustedes   an   en   en

Given a pronoun and a verb, print the verb conjugated using the pronoun in the present tense. Don't worry about stem changing and odd verbs.


Input        Output
Yo escribir  Escribo
Tu enseñar   Enseñas
Ella querer  Quere (It should be quiere but ignore stem changes)

If your language doesn't support printing with accents, you can omit them. Otherwise, it shouldn't take any more characters to use á instead of a in your code.

You can find more words with which to test here: http://spanish.speak7.com/spanish_vocabulary_verbs.htm. Note that contester should be contestar.

Challenge: Stem Changes

In Spanish, some verbs have stem changes. Let's take the verb querer for example. In all forms except nosotros and vosotros, the first e changes to ie. So, yo quiero, but nosotros queremos. If your program can account for stem changes, you may subtract twice the length of each word you support from your final score. For example, if you support the i -> ie change querer and only querer, you can subtract twice the length of querer, or 12, from your score.

For some stem-changing verbs, try this: https://conjuguemos.com/chart.php?language=spanish&id=2&etre=no&commands=no&all=no&source=public

Small Bonuses

Just for fun, if you explain what your code does in Spanish, take off 30 from your score. Don't just use Google Translate or I'll be able to tell that you cheated.

(As I am not a native Spanish speaker, please correct me on any mistakes)

  • 2
    \$\begingroup\$ I don't take Spanish: I just speak it; but a) is the nominative form of the pronoun: tu is genitive; b) verbs aren't "paired" with pronouns; c) nominative pronouns are rarely used in Spanish, so this exercise teaches bad habits; d) you should mention that this is only conjugating the present indicative; e) you haven't said how to handle pronomial (aka reflexive) verbs; f) the most common verbs are irregular, so this isn't a practical tool: if you want to make a verb conjugation question without worrying about irregularities you should use Esperanto instead of Castellano. \$\endgroup\$ – Peter Taylor Mar 14 '14 at 15:50
  • 1
    \$\begingroup\$ a) Fixing that now. b) Fair enough, fixing. c) True, but this is meant more as a challenge than a useable tool. I could remove the requirement to print the pronoun (yo escribir -> escribo) but I'd rather leave it in. f) I'll just leave it in "normal" Spanish and add a challenge for "special" verbs. Hope I didn't come off as rude, I appreciate the feedback. \$\endgroup\$ – nrubin29 Mar 14 '14 at 16:39
  • 4
    \$\begingroup\$ While I was in the middle of working on my answer, you changed the scoring by adding a bonus challenge! I'm no longer interested in golfing this because of the additional bonus score modification and the promise of more changes to come. I already wasted an hour on it, and that hour has become your downvote. \$\endgroup\$ – Rainbolt Mar 14 '14 at 20:30
  • 2
    \$\begingroup\$ @nrubin29: I didn't downvote but I agree w/ Rusher. You shouldn't change the scoring and rules after the question has been posted - especially after an answer has already been posted. Use the sandbox if you're not happy w/ the question yet. \$\endgroup\$ – Claudiu Mar 14 '14 at 20:34
  • 1
    \$\begingroup\$ @grovesNL at least that -30 doesn't make a huge difference. The thing that's killed this question is the unlimited bonus for stem changing verbs. I thought we'd ironed out the ambiguities for the OP, then he suddenly threw in two new bonuses and offended Rusher. Hopefully he'll learn to think ahead, use the sandbox, and not add bits to his questions after posting. It's too late to go back now. \$\endgroup\$ – Level River St Mar 15 '14 at 19:05

10 Answers 10


Python, 172 168 743 characters - 1796 bonus = -1053

Updated to take the stem-changing challenge.

if s in X:
print s+x["aei".index(v[-2])]+x[3:]


$ echo "Ellas querer" | python conj_golf2.py

Test on non-stem-changing inputs:

Yo ensenar -> enseno
Yo escribir -> escribo
Tu ensenar -> ensenas
Tu escribir -> escribes
El ensenar -> ensena
El escribir -> escribe
Ella ensenar -> ensena
Ella escribir -> escribe
Usted ensenar -> ensena
Usted escribir -> escribe
Nosotros ensenar -> ensenamos
Nosotros escribir -> escribimos
Vosotros ensenar -> ensenais
Vosotros escribir -> escribis
Ellos ensenar -> ensenan
Ellos escribir -> escriben
Ellas ensenar -> ensenan
Ellas escribir -> escriben
Ustedes ensenar -> ensenan
Ustedes escribir -> escriben

Stem-changing input examples:

It does both e->ie changes and o->ue changes, properly avoiding the nostros + vostros cases:

$ echo "Yo abstenir"|python conj_golf2.py
$ echo "Nostros abstenir"|python conj_golf2.py
$ echo "Tu almorzar"|python conj_golf2.py
$ echo "Vostros almorzar"|python conj_golf2.py

Here is how the bonus was determined and the data string generated, from which you can deduce the verbs on which it works:



words = e.split(".") + u.split(".")
bonus = 0
for word in words:
    bonus += (len(word)+2)*2
print "Bonus: %d from %d stem-changing verbs" % (bonus, len(words))

zipped = s.encode('zip')
b64 = zipped.encode('base64')
print "The separator is at index %d" % s.index("|")
print "Uncompressed: %d chars, %d repr" % (len(s), len(`s`))
print "Compressed: %d chars, %d repr" % (len(zipped), len(`zipped`))
print "Comp+B64: %d chars, %d repr" % (len(b64), len(`b64`))

print "v="+`b64`

Which gives:

$ python conj_help.py
Bonus: 1796 from 127 stem-changing verbs
The separator is at index 326
Uncompressed: 645 chars, 647 repr
Compressed: 331 chars, 1015 repr
Comp+B64: 450 chars, 458 repr
  • \$\begingroup\$ I'll be staying away from the stem changes because it becomes question of linguistics rather than programming. Acordar should be Acord**, surely? And you can't give the right answer for both regar> riego,riegas etc and regir> rijo, riges etc. \$\endgroup\$ – Level River St Mar 14 '14 at 21:52
  • \$\begingroup\$ @steveverrill: oh yep I guess "acordar" slipped through. True I can't deal with same verbs of different stem but e.g. "regir" would be wrong anyway since I don't do g->j . Accuracy is not so important for this one. I see your point but I couldn't give up the enormous boon of bonus points =). \$\endgroup\$ – Claudiu Mar 14 '14 at 22:09
  • \$\begingroup\$ @steveverrill: Also there's chance for error if there's a verb that happens to fit in the concatenated verbs put together. e.g. if there's a regular verb "tenacar" it will be conjugated as a stem-changing one. This I can fix by leaving in the .s, would add 50 pts or so to the score \$\endgroup\$ – Claudiu Mar 14 '14 at 22:12
  • \$\begingroup\$ I'm trying to deduce the verb for which you have ten in your list of roots. teñir is e to i, not e to ie; tener is e to ie, but has an irregular stem change for 1s. Similarly abstener, circunvenir, obtener, sostener, venir, cocer, destorcer, oler, retorcer, torcer. On the other hand, your scoring script doesn't seem to count both sentar and sentir. And you're missing a . in sosegsosten, and descontr should probably be descont. \$\endgroup\$ – Peter Taylor Mar 18 '14 at 22:31
  • \$\begingroup\$ @PeterTaylor: It is tener I think. I didn't realize those verbs you listed had a special case. I can remove them or account for them (whichever is cheaper) and fix the typos if there's another close contender \$\endgroup\$ – Claudiu Mar 18 '14 at 22:52

Python, 240 bytes - (extremely large) bonus

from re import*;import urllib2 as u,sys;x=sys.argv
 print search('>.*?'+sub('a','o',sub('ella','el',x[1]))+'.*? ([^<]*)',sub(u'\u00e9','e',sub(u'\u00fa','u',u.urlopen("http://smarturl.it/xz?word="+x[2]).read()))).group(1)

Sample Output:

Input         | Output
yo escribir   | escribo
tu escribir   | escribes
tu ensenar    | ensenas
ella querer   | quiere
ellas querer  | quieren
nosotros vive | vi
tu acordar    | acuerdas


This code uses an existing free conjugation website (http://www.conjugation.org/) that returns various conjugations from a large database of verbs. I reduced the URL slightly by using a free online URL shortener that allows parameters to be passed through the redirection (http://smarturl.it/). I simply make a HTTP request based on the verb specified, remove the accents from the u and e in the source, find the pronoun in the HTML using regular expressions, then return associated conjugation.

It's impossible to tell how many verbs have stem changes without polling the entire database against a dictionary. It's probably safe to assume the negative bonus from this database is much larger than any bonus from encoded lists passed in (which increase the length of the code).

I could obviously have handled the accented characters better, but it would've required encode/decode and extra handling within the regular expressions.

  • 4
    \$\begingroup\$ No longer funny \$\endgroup\$ – Claudiu Mar 15 '14 at 21:09
  • \$\begingroup\$ @Claudiu: It's not supposed to be a loophole - that post is not relevant here. The question itself has serious flaws which make some kind of external dependency necessary. Passing in a base64-encoded string of data isn't better than connecting to an external data source. \$\endgroup\$ – grovesNL Mar 15 '14 at 22:00
  • \$\begingroup\$ It is better because it is counted as part of my score. My script is entirely self-contained and actually does the conjugation work. Yours just retrieves it from an external data source. You can't even count your score because it depends entirely on how many verbs that data source processes. If that site or the URL shortener goes down then your answer becomes invalid. \$\endgroup\$ – Claudiu Mar 15 '14 at 22:42
  • \$\begingroup\$ @Claudiu: Regardless, it's irrelevant because the question is best suited to reference an external database. The conjugations themselves are as trivial as using re.sub or string.replace when not having to handle stem changes, etc. Even your program would receive a greater negative score if you keep adding further stem changing verbs to your encoded list. The question is flawed. \$\endgroup\$ – grovesNL Mar 15 '14 at 23:18
  • 1
    \$\begingroup\$ @Claudiu , grovesNL Hahaha. Haha. Calm down both of you. It is funny in this case because the question is flawed. It's only a game and both of you have errors in your Spanish. It's going to be impossible to call a winner on this because of that flaw. The win is only 15 reputation anyway. Here, have an upvote each and play nicely. \$\endgroup\$ – Level River St Mar 19 '14 at 17:45

Freepascal, 218 chars -30 = 189

It's a tough call to beat the (original) python answer, especially with Pascal. I may try and improve tomorrow, possibly with a similar concept in a different language. I will not be submitting a stem-changing answer, as I see this as a linguistic rather than programming challenge.

var y,p,v:string;BEGIN y:='amosemosimosais eis is  as  eso eso   o   an  en  en';readln(p);readln(v);writeln(copy(v,1,length(v)-2),copy(y,6*(7-pos(p[1],' yt v n'))+pos(v[length(v)-1],y),pos(p[length(p)],'u s')+1));END.

Ungolfed version:

var y,p,v:string;
  y:='amosemosimosais eis is  as  eso eso   o   an  en  en';
  copy(y,6*(7-pos(p[1],' yt v n'))+pos(v[length(v)-1],y),pos(p[length(p)],'u s')+1));

Explicación (In Spanish for the -30 bonus since you asked)

el primer copy extrae la raíz del verbo, teniendo como parámetros el string, el indice para empezar (en este caso 1) y la cantidad de letras (en este caso length-2.) El segundo extrae su desinencia.

6*(7-pos(p[1],' yt v n') se evalúa según la primera letra del pronombre. Si el pronombre es él/ella(o/s) o usted(es),pos se evalúa a cero, así que el valor dentro de los paréntesis es 7. pos(v[length(v)-1],y busca la penúltima letra del infinitivo en amosemosimos así que avanza 4 por cada tipo de verbo, formando un ciclo de 12. El resto de y consiste en todas las desinencias. Se ha logrado intercalar parcialmente las desinencias para "tu" y "yo." Sin embargo queda cierta cantidad de espacio en blanco que me gustaría eliminar. Así se define el indice para buscar la desinencia en y.

pos(p[length(p)],'u s')+1) determina el numero de caracteres para imprimir. si el pronombre no termina en s o u solo se imprime un cáracter. De esta manera suprimimos la segunda letra de an en en en el caso de un pronombre de tercera persona singular: él, ella, usted.


enter image description here


JavaScript (V8), 191 bytes

  • \$\begingroup\$ Was going to outgolf you and the other JS answer, then realized that I made a small mistake :( \$\endgroup\$ – ophact Apr 6 at 16:26
  • \$\begingroup\$ @ophact Wouldn't be surprised if there way a way to outgolf me by 20 bytes :p \$\endgroup\$ – Redwolf Programs Apr 6 at 16:27

perl, 243 chars

This time focusing on hash lookup. I'm fairly surprised I couldn't get this smaller.

$_=<>;s/^(ustede|ell[oa])s\b/x/;s/^(él|ella|usted)\b/w/;%t=(yo,[o,o,o],"tú",[es,as,es],w,[e,a,e],x,[en,an,en],nosotros,[imos,amos,emos],vosotros,[qw(ís áis éis)]);@t=keys%t;$"="|";s/^(@t)\s+(\S*)([aei])r$/$2.$t{$1}[ord($3)%3]/e||die;print

And if input validation isn't important, 186 chars:

$_=<>;s/^[ue].*s /x /;s/^[éeu].* /w /;%_=(y=>[o,o,o],t,[es,as,es],w,[e,a,e],x,[en,an,en],n,[imos,amos,emos],v,[qw(ís áis éis)]);s/^(.)\S*\s+(.*)([aei])r$/$2.$_{$1}[ord($3)%3]/e;print
  • \$\begingroup\$ Is this an improved answer to your last answer? \$\endgroup\$ – nrubin29 Mar 19 '14 at 1:11
  • \$\begingroup\$ I posted 3 different answers with 3 different methods. The best by char count is the regular expression one. \$\endgroup\$ – skibrianski Mar 19 '14 at 1:42
  • \$\begingroup\$ Got it. Thanks for the submissions! \$\endgroup\$ – nrubin29 Mar 19 '14 at 11:07

perl, 155 chars

Just a bunch of regular expressions this time. You can get shorter code by rearranging things slightly so that the pronoun comes after the verb, since we only really care about the end of the verb:

$_=<>;s/(.+) (.*)(.)r/$2$3 $1/;s/. yo/o/||s/ tú/s/||s/ n.*/mos/||s/ v.*/is/||s/ .*s$/n/||s/ .*//;s/i(n?)$/e$1/;s/ais$/áis/;s/eis$/éis/;s/iis$/ís/;print

Seems like the above is currently the winner of code that ignores the bonus.

ski@anito:~$ c='$_=<>;s/(.+) (.*)(.)r/$2$3 $1/;s/. yo/o/||s/ tú/s/||s/ n.*/mos/||s/ v.*/is/||s/ .*s$/n/||s/ .*$//;s/i(n?)$/e$1/;s/ais$/áis/;s/eis$/éis/;s/iis$/ís/;print'; for p in yo tú él ella usted ellos ellas ustedes vosotros nosotros ; do for v in mar mer mir ; do echo "$p $v" | perl -e "$c" ; done ; done ; echo -n "$c" | wc -c

Bash, 301 309 (bugfix) 307 299 including new lines

Not great compared to the other ones out there. Could be improved.

It exploits some convenient coincidences.

The bugfix relies on no Spanish verb having "ii" anywhere, due to the way it saves characters when handling vosotros with -ir verbs. Please correct me if that's wrong.

Assumes valid input: first argument is the lower case pronoun, with any necessary accents; second argument is the infinitive of the verb. No stem changes implemented. Outputs the conjugated verb, in lower case, without accents.

e=`tail -c3<<<$2`
f=`echo ${e:0:-1}`
s=`echo ${2:0:-2}`
if [ $1 = yo ];then o="$s"o;elif [ $1 = nosotros ];then o="$s$f"mos;elif [ $1 = vosotros ];then o="$s$f"is;else
if [ $f = i ];then f=e;fi
if [ $1 = tú ];then
o="$s$f"s;elif [ `tail -c2<<<$1` = s ];then
o="$s$f"n;else o=$s$f;fi
tr -s i<<<$o

Explained. ` ` is an obscure notation for $( ), saving one char.

e=`tail -c3<<<$2`

get the verb ending

f=`echo ${e:0:-1}`

get the first char of the verb ending

s=`echo ${2:0:-2}`

get the verb stem

if [ $1 = yo ]; then

Verb stem+o. $o is our output

elif [ $1 = nosotros ]; then

take stem+first letter of ending+mos

elif [ $1 = vosotros ]; then

stem+first letter of ending+is (no accents)

if [ $f = i ];then f=e;fi

in all scenarios except the two above, -ir verbs behave as -er verbs. change $f to e if it is i.

if [ $1 = tú ]; then


elif [ `tail -c2<<<$1` = s ]; then 

if the last letter of the ending is s. this includes ellos, ellas, ustedes which all have the same endings. how convenient.



else o=$s$f;fi

we are assuming valid input, so the only other possibilities are Él, Ella and Usted, all with the same endings

tr -s i <<< $0

print output, removing double i's (which appear when you use vosotros with an ir verb)


Java – Too Long

I'm not even going to bother counting. If anyone would like to better golf this, please do. I'll eventually implement the stem-changing challenge.

public class Conjugator {
    public static void main(String[] args) {
        String p = args[0].toLowerCase(), v = args[1]; 
        String e = v.substring(v.length() - 2);
        v = v.substring(0, v.length() - 2);
        String f = data.get(e).get(p);
        System.out.println(v + f);
    static HashMap<String, HashMap<String, String>> data = new HashMap<String, HashMap<String, String>>();
    public static void add(String ending, String pronoun, String fin) {
        HashMap<String, String> hm = data.get(ending);
        if (hm == null) {
            hm = new HashMap<String, String>();
            hm.put(pronoun, fin);
            data.put(ending, hm);
        hm = data.get(ending);
        hm.put(pronoun, fin);
    public static void setup() {
        add("ar", "yo", "o");
        add("ar", "tu", "as");
        add("ar", "el/ella/usted", "a");
        add("ar", "nosotros", "amos");
        add("ar", "vosotros", "ais");
        add("ar", "ellos/ellas/ustedes", "an");
        add("er", "yo", "o");
        add("er", "tu", "es");
        add("er", "el/ella/usted", "e");
        add("er", "nosotros", "emos");
        add("er", "vosotros", "eis");
        add("er", "ellos/ellas/ustedes", "en");
        add("ir", "yo", "o");
        add("ir", "tu", "es");
        add("ir", "el/ella/usted", "e");
        add("ir", "nosotros", "imos");
        add("ir", "vosotros", "is");
        add("ir", "ellos/ellas/ustedes", "en");

perl, 298 characters

$_=<>;($p,$b,$x)=/^\s*(yo|tú|él|ellas?|ellos|usted|ustedes|[nv]osotros)\s+(\S*)([aei])r\s*$/;sub r{($z,$y)=@_;return if$p!~/^($z)/;if($p!~/ros$/){$x="e" if$x eq"i"}$x=""if$z eq yo;$x={qw(a áis e éis i ís)}->{$x}if$p=~/^v/;print"$b$x$y";exit}r yo,o;r t,"s";r"[eu].+s",n;r"[éeu]","";r n,mos;r v

or if we can throw caution to the wind and assume valid input, 246 chars:

$_=<>;($p,$b,$x)=/^(\S+)\s+(\S*)([aei])r$/;sub r{($z,$y)=@_;return if$p!~/^($z)/;if($p!~/ros$/){$x="e" if$x eq"i"}$x=""if$z eq yo;$x={qw(a áis e éis i ís)}->{$x}if$p=~/^v/;print"$b$x$y";exit}r yo,o;r t,"s";r"[eu].+s",n;r"[éeu]","";r n,mos;r v

test output:

ski@anito:~$ c='$_=<>;($p,$b,$x)=/^(\S+)\s+(\S*)([aei])r$/;sub r{($z,$y)=@_;return if$p!~/^($z)/;if($p!~/ros$/){$x="e" if$x eq"i"}$x=""if$z eq yo;$x={qw(a áis e éis i ís)}->{$x}if$p=~/^v/;print"$b$x$y";exit}r yo,o;r t,"s";r"[eu].+s",n;r"[éeu]","";r n,mos;r v'; for p in yo tú él ella usted ellos ellas ustedes vosotros nosotros ; do for v in mar mer mir ; do echo "$p $v" | perl -le "$c" ; done ; done ; echo -n "$c" | wc -c
  • \$\begingroup\$ I think it would be ok to assume valid input, but I didn't state that before. What do you guys think? \$\endgroup\$ – nrubin29 Mar 18 '14 at 19:20
  • \$\begingroup\$ @nrubin29 If you didn't state we had to handle invalid input, then we assume we don't have to handle it. (It would have been best to state explicitly in the question that we didn't have to handle it though.) If we did have to handle it, you would have to specify how. This is code golf, virtually all answers here can be broken with invalid input. Also Rusher and I discussed whether it was necessary to parse the whole pronoun in the comments on the question (He deleted his part, but mine is still there.) BTW, you absolutely made the right decision saying that we didn't have to handle accents. \$\endgroup\$ – Level River St Mar 19 '14 at 19:30
  • \$\begingroup\$ I'll add to the guidelines that valid input can be assumed as long as that doesn't count as "changing the rules". Don't want to anger anyone anymore. Also, when do I accept an answer? After a week? \$\endgroup\$ – nrubin29 Mar 20 '14 at 2:23

JavaScript (Node.js), 195 bytes


Try it online!

Doesn't handle the stem changes. It would cost a few more bytes to add the accents to the Vosotros form conjugations. If the input has accents, the output will include them. Also, it doesn't matter if accents are included in the pronouns or not; my program happens to ignore the characters that have accents on them.

  • \$\begingroup\$ HAHA I outgolfed you anyway :p \$\endgroup\$ – Redwolf Programs Apr 6 at 15:29
  • \$\begingroup\$ @RedwolfPrograms :c lol fair enough. i don't use JS much i just did it to snipe you :P \$\endgroup\$ – hyper-neutrino Apr 6 at 15:34

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.