I programming puzzles, il code golf

Retina, 138 133 129 113 bytes

^.(s[^aeiou]|z|gn|pn|ps|x|i[aeiou])
B$&
^.[aeiou]
V$&
^\d.
A$&
V[02]
l'
A0
il 
B0
lo 
A1
i 
.1
gli 
.2
la 
.3
le 

Test suite. (prepended %(G`\n to run all test-cases at once)

Input format: macchina f s becomes 2macchina instead.

0: Masculine Singular
1: Masculine Plural
2: Feminine Singular
3: Feminine Plural

Conversion table thanks to Kevin Lau.


Python 3.5, 238 235 192 181 178 bytes:

(-13 bytes thanks to tips from Leaky Nun!)

import re;R=re.match;lambda a,b:(R('s[^aeiou]|(z|gn|pn|ps|x|i)[aeiou]',a)and['lo ','gli ','la '][b]or R('[aeiou]',a)and["l'",'gli '][b%2]or['il ','i ','la '][b]if b<3else'le ')+a

An anonymous lambda function that takes arguments in the form of (<String>, <Integer Gender-Plurality mapping>), where the mapping is as follows:

0 -> Masculine Singular
1 -> Masculine Plural
2 -> Feminine Singular
3 -> Feminine Plural

To call it, simply give the function any valid name, and then call it like a normal function wrapped inside a print statement. Therefore, if the question were to be named U, simply call it like print(U(<String>, <Integer Gender-Plurality mapping>)).

Try It Online! (Ideone)


Java, 227 208 195 bytes

-13 bytes thanks to Leaky Nun

String f(String a,int o){boolean v=a.matches("^([aeou]|i[^aeiou]).*"),b=a.matches("^([ixz]|gn|pn|ps|s[^aeiou]).*");return(o>1?o>2?"le ":v?"l'":"la ":o>0?v||b?"gli ":"i ":v?"l'":b?"lo ":"il ")+a;}

Takes your string and an int based on the following mapping:

0: Masculine Singular
1: Masculine Plural
2: Feminine Singular
3: Feminine Plural

Returns a string with the result.

Ungolfed with test cases and with no ternary operators (for real now):

class Test {

    public static String f(String a, int o) {
        boolean v = a.matches("^([aeou]|i[^aeiou]).*");
        boolean b = a.matches("^([ixz]|gn|pn|ps|s[^aeiou]).*");
        String r;
        if(o > 1)
            if(o > 2)
                r = "le ";
            else
                if(v)
                    r = "l'";
                else
                    r = "la ";
        else
            if(o > 0)
                if(v || b)
                    r = "gli ";
                else
                    r = "i ";
            else
                if(v)
                    r = "l'";
                else if(b)
                    r = "lo ";
                else
                    r = "il ";
        return r + a;
    }
    
    public static void main(String[] args) {
        System.out.println(f("macchina", 2));
        System.out.println(f("zio", 0));
        System.out.println(f("libri", 1));
        System.out.println(f("ieri", 0));
        System.out.println(f("aquile", 3));
        System.out.println(f("spagnoli", 1));
        System.out.println(f("golf", 0));
        System.out.println(f("ombra", 2));
        System.out.println(f("impossibili", 1));
    }
}

Uses a little bit of regex magic and acts depending on the two booleans specified. To my surprise, no imports are needed, which helps out with the code size!