text:
N in a row (or column)!
N in a row
Input:
The character and a 2-Dimensional array.
The array with a size of N x N where 1 <= N <= 26, it will be filled randomly like so:
N = 1
A

N = 2
B | A
-----
A | B

N = 3
A | B | C
----------
B | A | B
----------
C | A | C

As N increases by 1, so does the number of letters. A = 1, B = 2, C = 3. There will always be N number of each letter.
N = 3, there will be 3 As... 3 Bs... 3 Cs...
N = 4, there will be 4 As... 4 Bs... 4 Cs... 4 Ds...
N = 5, there will be 5 As... 5 Bs... 5 Cs... 5 Ds... 5 Es...
Output:
The original matrix as well as a manipulated matrix where any given letter has N in a row (or column).
Manipulations occur by swapping two letters within the 2-D grid that are adjacent on the x or y axis. You may not swap characters over the boundaries of the array. I.E. You cannot swap Array[0][N-1] with Array[0][0]. You also may not swap characters diagonally.
Objective:
Your job is to pick a character C to solve for given N. Swap characters within the matrix so that there are N of C in the same row or column.
Examples:
N = 3, C = A
A | B | C
----------
B | A | B
----------
C | A | C

Swap array[0][0] (A) with array[1][0] (B)
resulting in
B | A | C
----------
B | A | B
----------
C | A | C

Complete
N = 4, C = B
A | B | C | D
--------------
B | D | B | A
--------------
D | A | C | C
--------------
A | C | B | D

swap array[1][0] (B) with array[1][1] (D)
A | D | C | D
--------------
B | B | B | A
--------------
D | A | C | C
--------------
A | C | B | D

swap array[2][3] (B) with array[3][3] (D)
A | D | C | D
--------------
B | B | B | A
--------------
D | A | C | C
--------------
A | C | D | B

swap array[3][3] (B) with array[3][2] (C)
A | D | C | D
--------------
B | B | B | A
--------------
D | A | C | B
--------------
A | C | D | C

swap array[3][2] (B) with array[3][1] (A)
A | D | C | D
--------------
B | B | B | B
--------------
D | A | C | A
--------------
A | C | D | C

Complete!
Any letter can be chosen to solve for. As this is code-golf the shortest code wins!
Have Fun and Good Luck!

Using those swaps I can generate any permutation of the matrix, so doesn't this just reduce to identifying the distinct elements and printing the matrix in which each fills a row?

@PeterTaylor The idea would be for you to input a random permutation where 1<=n<=26. Then solve for each problem. There are times where the grid will be solved on input, but you would need to handle every case.

My point is that it can be "solved" without doing any work. You were already pointed at http://meta.codegolf.stackexchange.com/a/10002/20283 in a comment on your previous question. I think that you're falling into the same trap again, but this time even worse, with the result that the specification is unusably vague.

@PeterTaylor Your code will prove the validity of the assignment. The instructions are clear, playing devil's advocate and poking holes in the question is silly when the code and output provided will prove any negatives.

So you need to output the matrix after each step? Or the coordinates of the swaps? Does the program need to end the first time it meets the criteria?

Python 2, 270 bytes
from random import*
e=lambda s,n:all(sum(map(ord,l))!=n*65for l in s)
R,C,d=randint,choice,[-1,1]
def w(a):
 print a;n=len(a);
 while e(a,n)and e(zip(*a),n):
    if n==2:x,y,w,z=0,0,0,1
    else:x,y=R(1,n-2),R(1,n-2);w,z=x+C(d),y+C(d)
    a[y][x],a[z][w]=a[z][w],a[y][x]
 print a

Always chooses A as character to complete a row/col. Performs random swaps until goal is reached.
Accepts the matrix as list of lists, usage for testing:
A="""ADCD
BBBA
DACC
ACDB"""
a=[[c for c in l] for l in A.split('\n')]
w(a)

A random solution. Nice

@jacksonecac Normally not my style but i thought it is quite helpful here. At first i did random swaps until any character reached the goal, but then i read in your description to pick one, so i did.

R, 41 40 bytes
This answer provides valid output, although it does not follow the algorithm suggested. Since a limitless number of swapping manipulations are permitted, restrictions on what manipulations are allowed (e.g. the diagonal restriction) are irrelevant, as any permutation of the matrix can be arrived at through a (possibly large) number of swaps. So, I've bypassed the "switching around" part of the matrix manipulation and just went straight to outputting a solved matrix.
Anonymous function that takes a matrix as input, and returns a list of the original matrix and the "solved" matrix.
function(m)list(m,array(sort(m),dim(m)))

Example input:
matrix(c("A","B","A","C","C","B","A","C","B"),3)

That is,

[,1] [,2] [,3]
[1,] "A"  "C"  "A"
[2,] "B"  "C"  "C"
[3,] "A"  "B"  "B"

Gives the following output:
[[1]]
     [,1] [,2] [,3]
[1,] "A"  "C"  "A"
[2,] "B"  "C"  "C"
[3,] "A"  "B"  "B"

[[2]]
     [,1] [,2] [,3]
[1,] "A"  "B"  "C"
[2,] "A"  "B"  "C"
[3,] "A"  "B"  "C"

While we're at it, here's a function to generate possible input matrices:
make_matrix = function(N) matrix(sample(rep(LETTERS[1:N], N)), N)

This function takes the first N letters of the alphabet, repeated N times (i.e. N*N characters) and randomly samples from them. The characters are then arranged into a matrix with N rows (and, implicitly, N columns).
Examples:
make_matrix(1)
     [,1]
[1,] "A"
> make_matrix(3)
     [,1] [,2] [,3]
[1,] "C"  "B"  "C"
[2,] "C"  "A"  "B"
[3,] "A"  "B"  "A"

And used with our function above (named f):
> f(make_matrix(10))
[[1]]
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,] "J"  "C"  "D"  "G"  "E"  "C"  "H"  "G"  "I"  "J"
 [2,] "C"  "D"  "A"  "C"  "H"  "A"  "A"  "E"  "H"  "I"
 [3,] "C"  "B"  "E"  "G"  "C"  "F"  "J"  "A"  "H"  "J"
 [4,] "I"  "E"  "F"  "I"  "B"  "G"  "E"  "F"  "F"  "C"
 [5,] "H"  "I"  "F"  "D"  "B"  "G"  "H"  "A"  "J"  "H"
 [6,] "J"  "E"  "D"  "J"  "A"  "D"  "B"  "D"  "G"  "B"
 [7,] "D"  "B"  "E"  "A"  "G"  "H"  "C"  "C"  "J"  "B"
 [8,] "H"  "D"  "I"  "J"  "B"  "I"  "I"  "F"  "E"  "I"
 [9,] "G"  "F"  "F"  "A"  "J"  "E"  "B"  "A"  "E"  "D"
[10,] "H"  "G"  "A"  "B"  "D"  "I"  "C"  "G"  "F"  "F"

[[2]]
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"
 [2,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"
 [3,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"
 [4,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"
 [5,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"
 [6,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"
 [7,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"
 [8,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"
 [9,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"
[10,] "A"  "B"  "C"  "D"  "E"  "F"  "G"  "H"  "I"  "J"

This doesn't follow the OP's instructions.

I wrote this: function super(Object) it calculates any answer to any problem you can ever think of.

@jacksonecac I'm sorry if my answer upset you. I'm afraid I am having difficulty in understanding why I am being downvoted. Could you explain in what way my answer doesn't meet your specifications? Is it because the matrix is not explicitly manipulated in the "swap array[0][0] with array[0][1]" sense?

You haven't provided any code, simply function names that don't do anything. You are assuming the output of all of your functions. The idea of code-golf is to provide the shortest possible code to achieve the solution to the given problem.

function(m)list(m,array(sort(m),dim(m))) is code. This defines an anonymous function in R. I'm not assuming the output of my functions, I pasted them from the R console after I ran my code! Do you mean that you want a full program, rather than a function? Your original post doesn't specify this, nor does it provide any indication as to what format the input is in, or how you would like the output. In the absence of this information, I wrote the shortest code I could.

sorting the array is not swapping two values, it is performing a sorting algorithm, which is not the intention of this question.

@jacksonecac Ah, so the question is based on a non-observable requirement? What if the sort function implements multiple swaps internally (e.g. bubble sort)? Would that satisfy the requirement? (Note that I don't know what R's sort actually does under the hood, this is a hypothetical question.)

So you submitted an answer to clear requirements without knowing what your code is doing? "Manipulations occur by swapping two letters within the 2-D grid that are adjacent on the x or y axis."

I know perfectly what my code is doing. When given an input matrix, as your question states, it returns an output matrix that meets your requirements. Your other requirements are unclear. How do you know if the manipulations occurred in the manner you wanted? What if my language does not allow direct modification in place, and I need to create copies of the object and change one cell at a time? Does that count as swapping or not? The requirements are not at all clear.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
The Rule of Thumb for Title Capitalization
According to this site a general rule recommended by The U.S. Government Printing Office Style Manual is

Capitalize all words in titles of publications and documents, except
  a, an, the, at, by, for, in, of, on, to, up, and, as, but, or, and
  nor.

This might not be true as I'm unable to find such a recommendation in the Style Manual, but let's use this rule anyway.

The Challenge
Given an input string consisting of lower case words delimited by spaces, output the capitalization of the string according to the following rules

The first and last word is capitalized.
All other words are capitalized, except a, an, the, at, by, for, in, of, on, to, up, and, as, but, or, and nor.

The input string will contain at least one word and each word contains at least one letter and only characters from a to z.
This is a code golf challenge, so try to use as few bytes as possible in the language of your choice. You may write a full program or a function to accomplish the task.
Testcases
"the rule of thumb for title capitalization" -> "The Rule of Thumb for Title Capitalization"
"programming puzzles and code golf" -> "Programming Puzzles and Code Golf"
"the many uses of the letter a" -> "The Many Uses of the Letter A"
"title" -> "Title"
"and and and" -> "And and And"
"a an and as at but by for in nor of on or the to up" -> "A an and as at but by for in nor of on or the to Up"
"on computable numbers with an application to the entscheidungsproblem" -> "On Computable Numbers With an Application to the Entscheidungsproblem"

Should beginning/ending words be capitalized even if they are in the exclusion list? Your examples say yes, but the spec just says capitalize words unless they are in the list, and nothing about first/last word. Note that the two possibilities are distinctly different, one being a simple filter and the second requiring special behavior in (literal) edge cases.

@CAD97 The rules for the capitalization are the two bullet points, not the Quote. And the first bullet point says "The first and last word is capitalized." and the second one says "All other words are capitalized, except ..." meaning first and last words are always capitalized.

I missed that, somehow. Still, thanks for clarifying.

I'm not sure it's really necessary to specify that each word contains at least one letter. :)

Python 2, 118 bytes
Look ma, no regex!
for w in`input()`.split():print[w.title(),w][`w`in"'a'an'and'as'at'the'by'but'for'nor'in'of'on'or'to'up'"].strip("'"),

Input must be wrapped in quotes. Output has a trailing space and no trailing newline (I assume that's okay). Verify all test cases on Ideone.
Explanation
Let's take the input a or an as our example.
Using Python 2's `x` shortcut for repr, we wrap the input in single quotes: 'a or an'. Then we split on whitespace and iterate over the words.
Inside the loop, we take the repr again. For the first and last words, this gives "'a" and "an'". For other words, it gives 'or'. We want to avoid capitalizing words if they fit the latter pattern and are in the short-words list. So we can represent the word list as the string "'a'an'...'up'" and know that the repr of any short word will be a substring.
`w` in "..." gives a boolean value, which we can treat as 0 or 1 for the purposes of indexing into the list [w.title(), w]. In short, we title-case the word if it is at the beginning, at the end, or not in the list of short words. Otherwise, we leave it alone. Fortunately, title() still works as expected with input like 'a.
Finally, we strip any single quotes from the word and print it with a trailing space.

05AB1E, 68 61 bytes
Saved 7 bytes thanks to Adnan
™ð¡Dg<UvyN__NXQ_“a€¤€€€›€‹€‡€†€‚€‰€„€¾€ƒ€œ€³€—š¯“#™yå&&il})ðý

Try it online!
Explanation
“a€¤€€€›€‹€‡€†€‚€‰€„€¾€ƒ€œ€³€—š¯“ is a dictionary string translated as a an the at by for in of on to up and as but or nor.
™                          # title case input string
ð¡                         # split on spaces
Dg<U                       # store index of last word in X

vy                         # for each word
  N__                      # is it not first index?
     NXQ_                  # is it not last index
         “...“             # the compressed string
              #            # split on spaces
               ™           # convert to title case
                yå         # is current word in this list?
                  &&       # and the 3 previous conditions together
                    il     # if all are true, convert to lower case
                      }    # end loop
)ðý                        # wrap stack in list and join by spaces

It Never Ceases to Amaze Me What You Manage to Achieve With a Short String of Totally Unrecognisible Characters. Looks like it works then :) +1

Bah! I'm so close, and I can't find a way to shave off a character.

@mbomb007: Better hurry up before Jelly, MATL or some other language that can apply functions to indices comes and beat this :) I seem to remember a language with compressed regex as well, but can't remember what it was called. This is long enough that it might still be golfable as well.

For 62 bytes :)

@Adnan: I started like that but only with the 3-char words (which ended up longer), but I didn't consider taking the 2-char words as well... a instead of €… saves an additional byte as well if lead of with it :) Thanks!

GNU sed 81 74 73 Bytes
Includes +1 for -r
s/\b./\u&/g
:;s/.(And?|A[st]?|The|By|But|[FN]or|In|O[fnr]|To|Up) /\L&/;t

The first line capitalizes the first letter of every word. The second switches all of the required words back to lowercase.
Try it Online!

Retina, 69 66 bytes
Capitalize the first letter of every word, then change the selected words to lowercase if they're not the first or last word. There's a space at the end of the last line.
T`l`L`\b.
+T`L`l` (And?|A[st]?|The|By|But|[FN]or|In|O[fnr]|To|Up)

Try it online
This also works with a . instead of the first space.
There are a lot of regexes with the same length, but I can't find a way to trim it anymore...

(This approach is also 69 bytes in Pip, but I can't use the + trick to shorten it.)

@DLosc Thanks. Idk why I didn't see that. I was close.

JavaScript (ES6), 141 138 135 133 bytes
Saved 3 bytes thanks to mbomb007
s=>s.replace(/(\w+)( ?)/g,(a,w,n,i)=>i&&n&&/^(a[nst]?|the|by|in|of|on|to|up|and|but|[fn]?or)$/.exec(w)?a:a[0].toUpperCase()+a.slice(1))

Test cases

let f =

s=>s.replace(/(\w)(\w*)( ?)/g,(a,l,w,n,i)=>i&&n&&/^(a[nst]?|the|by|in|of|on|to|up|and|but|[fn]?or)$/.exec(l+w)?a:l.toUpperCase()+w+n)

console.log(f("the rule of thumb for title capitalization"));
console.log(f("programming puzzles and code golf"));
console.log(f("the many uses of the letter a"));
console.log(f("title"));
console.log(f("and and and"));
console.log(f("a an and as at but by for in nor of on or the to up"));
console.log(f("on computable numbers with an application to the entscheidungsproblem"));

Jelly, 58 bytes
“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’b26ịØaṣ”z
e€¢¬T;2Ḷ¤
ḲŒtÇ¦K

TryItOnline! or run all tests
How?
A compressed string with spaces separating the words would be 47 bytes, splitting it costs 1 byte, for 48 bytes.
Two unseparated compressed strings of the words of length 2 and 3 (with an 'a' on the end of one) respectively would be 40 bytes plus 2 to split each and 1 to join them, for 45 bytes.
One base 250 number as described below is 32 bytes, then 3 to convert to base 26, 3 to index into the lowercase alphabet and 3 to split it on the unused character, 'z', for 41 bytes.
So, the lookup for the words not to capitalise:
“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’
was formed like so:
Take those words and join them with a separator:
s="a an the at by for in of on to up and as but or nor"
Next label 'a' as 1, 'b' as 2 with the separator as 0:
alpha = ' abcdefghijklmnopqrstuvwxyz'
x = [alpha.index(v) for v in s]
x
[1,0,1,14,0,20,8,5,0,1,20,0,2,25,0,6,15,18,0,9,14,0,15,6,0,15,14,0,20,15,0,21,16,0,1,14,4,0,1,19,0,2,21,20,0,15,18,0,14,15,18]

Convert this into a base 26 number (the last letter used is 'y' plus a digit for the separator, Python code for this is:
n=sum(v*26**i for i,v in enumerate(x[::-1]))
Convert that into a base 250 number (using a list for the digits):
b=[]
while n:
    n,d = divmod(n,250)
    b=[d]+b
b
[16,48,220,145,8,32,202,209,162,13,45,142,244,153,9,80,207,75,35,161,52,18,108,103,52,205,24,38,237,118]

Lookup the characters at those indexes in jelly's codepage:
codepage = '''¡¢£¤¥¦©¬®µ½¿€ÆÇÐÑ×ØŒÞßæçðıȷñ÷øœþ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQR TUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~¶°¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ƁƇƊƑƓƘⱮƝƤƬƲȤɓƈɗƒɠɦƙɱɲƥʠɼʂƭʋȥẠḄḌẸḤỊḲḶṂṆỌṚṢṬỤṾẈỴẒȦḂĊḊĖḞĠḢİĿṀṄȮṖṘṠṪẆẊẎŻạḅḍẹḥịḳḷṃṇọṛṣṭụṿẉỵẓȧḃċḋėḟġḣŀṁṅȯṗṙṡṫẇẋẏż«»‘’“”'''
r=''.join(codepage[i-1] for i in b)
r
'Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu'

(note: since the actual implementation is bijective, if b had any 0 digits one would need to carry down first)
The rest:
ḲŒtÇ¦K - Main link: title string
Ḳ      - split on spaces
    ¦  - apply to indexes
   Ç   -     given by calling the last link (1) as a monad (with the split title string)
 Œt    -     title case (first letter of each (only) word to upper case)
     K - join on spaces

e€¢¬T;2Ḷ¤ - Link 1, find indexes to capitalise: split title string
e€        - is an element of, for €ach
  ¢       - the result of calling the last link (2) as a nilad
   ¬      - logical not
    T     - get the truthy indexes (indexes of words that are not in the list)
     ;    - concatenate with
        ¤ - nilad followed by link(s) as a nilad
      2Ḷ  - range(2) -> [0,1]
                (we always want to capitalise the first index, 1, and the last index, 0)

“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’b26ịØaṣ”z - Link 2, make the word list: no arguments
“Ð/ṃƇ¬þṄẊƙ€,⁽ṙƬ®OṪJ"ɦ3×kf3Ṙç%ġu’          - the base 250 number
                                b26       - convert to base 26
                                   ị      - index into
                                    Øa    - lowercase alphabet
                                      ṣ   - split on
                                       ”z - literal 'z' (the separator 0 indexes into `z`)

PHP, 158 Bytes
10 Bytes saved by @Titus
foreach($w=explode(" ",$argv[1])as$k=>$v)echo" "[!$k],$k&&$k+1<count($w)&&preg_match("#^(a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf])$#",$v)?$v:ucfirst($v);

Previous version PHP, 174 Bytes
foreach($w=explode(" ",$argv[1])as$k=>$v)$k&&$k+1<count($w)&&in_array($v,[a,an,the,at,by,"for",in,of,on,to,up,"and","as",but,"or",nor])?:$w[$k]=ucfirst($v);echo join(" ",$w);

Echoing in the loop saves 10 bytes: foreach(...)echo" "[!$k],(condition)?$v:ucfirst($v);

Java 7, 271 259 258 bytes
String c(String x){String a[]=x.split(" "),s=" ",r=w(a[0])+s;for(int i=0,l=a.length-1;i<l;r+=(!s.matches("^(a[nst]?|the|by|in|of|on|to|up|and|but|[fn]?or)$")|i==l?w(s):s)+" ")s=a[++i];return r;}String w(String w){return(char)(w.charAt(0)-32)+w.substring(1);}

Ungolfed & test code:
Try it here.
class M{
  static String c(String x){
    String a[] = x.split(" "),
           s = " ",
           r = w(a[0]) + s;
    for(int i = 0, l = a.length-1; i < l; r += (!s.matches("^(a[nst]?|the|by|in|of|on|to|up|and|but|[fn]?or)$") | i == l
                                                 ? w(s)
                                                 : s)   + " "){
      s = a[++i];
    }
    return r;
  }

  static String w(String w) {
    return (char)(w.charAt(0) - 32) + w.substring(1);
  }

  public static void main(String[] a){
    System.out.println(c("the rule of thumb for title capitalization"));
    System.out.println(c("programming puzzles and code golf"));
    System.out.println(c("the many uses of the letter a"));
    System.out.println(c("title"));
    System.out.println(c("and and and"));
    System.out.println(c("a an and as at but by for in nor of on or the to up"));
    System.out.println(c("on computable numbers with an application to the entscheidungsproblem"));
  }
}

Output:
The Rule of Thumb for Title Capitalization
Programming Puzzles and Code Golf
The Many Uses of the Letter A
Title
And and And
A an and as at but by for in nor of on or the to Up
On Computable Numbers With an Application to the Entscheidungsproblem

TI-Basic, 295 + 59 + 148 = 502 bytes
Now you can capitalize on your calculator. Great for school :)
Main Program, 295 bytes
Basically, the trick to matching words so all A don't become a is to enclose with spaces, such as replace " A " with " a ". This also automatically makes it so that the first and last words stay capitalized, because they do not have a space on both sides and will thus not match any of the words. (Genius, right? And super long because lowercase letters are two  bytes each...)
"("+Ans+")→Str1
"@A ~ a@An ~ an@The ~ the@At ~ at@By ~ by@For ~ for@In ~ in@Of ~ of@On ~ on@To ~ to@Up ~ up@And ~ and@As ~ as@But ~ but@Or ~ or@Nor ~ nor@→Str2
For(I,2,length(Ans
If "@"=sub(Str2,I-1,1
Then
" "+Str1+"~"+sub(Str2,I,inString(Str2,"@",I)-I)+" "
prgmQ
Ans→Str1
End
End

Subprogram (prgmQ), 59 bytes:
Ans→Str9
inString(Ans,"~
sub(Str9,Ans,length(Str9)-Ans+1→Str8
Str9
prgmR
Repeat Str9=Ans+Str8
Ans+Str8→Str9
prgmR
End

Subprogram (prgmR), 148 bytes:
Ans→Str0
inString(Ans,"~→Z
inString(Str0,"~",Ans+1→Y
inString(sub(Str0,1,Z-1),sub(Str0,Z+1,Ans-Z-1→X
sub(Str0,1,-1+inString(Str0,"~
If X
sub(Str0,1,X-1)+sub(Str0,Y+1,length(Str0)-Y)+sub(Str0,X+length(sub(Str0,Z+1,Y-Z-1)),Z-X-length(sub(Str0,Z+1,Y-Z-1

P.S. ~ represents token 0x81 and @ represents token 0x7F, learn more here.

Groovy, 131 129
Two bytes saved thanks to carusocomputing
{it.split()*.with{a->a in "a an the at by for in of on to up and as but or nor".split()?a:a.capitalize()}.join(" ").capitalize()}

Nice, I was at 137; you win. Remove it i-> and use it to save 2 bytes. {it.split()*.with{a->a in "a an the at by for in of on to up and as but or nor".split()?a:a.capitalize()}.join(" ").capitalize()}

I don't know Groovy but does this really capitalize the first and last word?

@Emigna the final capitalize covers starting with one of the words.

@Emigna not really, I missed that requirement (that last word needs to be capitalized). I would need to adjust my anwser.

The two uses of .capitalize() take up a lot of bytes. Is there a short way you can make an alias to .capitalize()?

Java 7, 431 317 311 bytes
Thanks to @KevinCruijssen for 114 bytes.

Thanks to @RosLup for saving 6 bytes.
String c(String s){String v="",x,l[]=s.split(" "),b[]={"a","an","the","at","but,"by","for","in","of","on","to","up","as","or","and","nor"};int i=0,f=0,z=0;for(String c:l){for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);x=(char)(c.charAt(0)-32)+c.substring(1);v+=(z>0?i<1|i>l.length-2?x:c:x)+" ";i++;}return v;}

ungolfed
first answer above 250 bytes
 static String c(String s) {
      String v = "", x, l[] = s.split(" "),
b[]={"a","an","the","at","by","for","in","of","on","to",
                                         "up","and","as","or","nor","but"};
    int i , f , z = i = f = 0;
    for (String c : l) {

   for (f = 0; f < b.length; z = c.equals( b[f++] ) | z > 0 ? 1 : 0);
        x = (char)(c.charAt(0) - 32) + c.substring(1);

        v += (z > 0 ? i < 1 | i > l.length - 2 ? x : c : x) + " ";
        i++;
   }
    return v;
    }

It was too much to summarize in a comment, but you can golf it to this: String f(String s){String v="",x,l[]=s.split(" "),b[]={"a","an","the","at","by","for","in","of","on","to","up","and","as","but","or","and","nor"};int i=0,f=0,z=0;for(String c:l){for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);x=(char)(c.charAt(0)-32)+c.substring(1);v+=z>0?i<1|i++==l.length-1?x:c:x)+" ";}return v;} (314 bytes) I suggest taking a look at what I changed as tips for next time. :) PS: I've posted an answer with a different approach (259 bytes).

Especially things like c.substring(0,1).toUpperCase()+c.substring(1,c.length())+" " which you did twice should make you think about re-using it somehow. And combined initializations like you did correctly with the int, but for some reason not with the String. Also, no need for the extra boolean when you can store at as an int 0 or 1 and then check it >0. And I would try to avoid brackets and break as much as possible; usually there is a trick to get rid of them, like the for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0); I've showed. :)

So much to learn and thanks for being helpful always (long live Nederland ;)

Oh, I've made a copy-paste error.. It should be this String c(String s){String v="",x,l[]=s.split(" "),b[]={"a","an","the","at","by","for","in","of","on","to","up","and","as","but","or","and","nor"};int i=0,f=0,z=0;for(String c:l){for(f=0;f<b.length;z=c.equals(b[f++])|z>0?1:0);x=(char)(c.charAt(0)-32)+c.substring(1);v+=(z>0?i<1|i++>l.length-2?x:c:x)+" ";}return v;} And no problem. :) I also learned a lot when I was new to code-golfing. I just make a list with every general codegolf tip I learn and look/update it sometimes. But my code still gets golfed by others a lot.

@KevinCruijssen v+=(z>0?i<1|i++>l.length-2?x:c:x)+" ";} should be this  v+=(z>0?i<1|i>l.length-2?x:c:x)+" ";i++;

In the string b[] there are 2 'and' is that ok?

PHP, 117 118 112 bytes
<?=strtr(ucwords(preg_replace("# (?=(a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf]) )#","!",$argv[1])),'!',' ');

Uses the behaviour of ucwords() and escapes the relevant words that are surrounded by spaces then deletes the escape characters.
I copied the (a[snt]?|and|[fn]or|up|by|but|the|to|in|o[rnf]) from Jörg Hülsermann's answer but as the approach is completely different I'm posting it as a separate answer.
edit: bug noticed by Titus, fixing it cost 1 byte. also: 6 bytes saved thanks to his helpful comment about strtr

Save 6 bytes with strtr instead of str_replace. Or prepend the words with <> and drop the str_replace and use HTML output.

In some cases you can use preg_filter instead of preg_replace. I have not try it with your solution

The regex will not work for two words from the list in a row; test nice try for a start. Replacing one of the spaces with an assertion solves that (+4 bytes).

Unfortunately preg_filter would fail on the title test case, returning nothing.

Python, 177 bytes
Delivered in function format for byte saving purposes. This is not an especially competitive answer, but it is one that doesn't require repr() or regex trickery. It is also version-agnostic; it works with Python 2 or 3.
Though it is perhaps a very by-the-rules solution.
def t(s):
 w="a an the the at by for in of on to up and as but or nor".split()
 l=[(s.title(),s)[s in w]for s in s.split()]
 for x in(0,-1):l[x]=l[x].title()
 return' '.join(l)

Racket 353 bytes
(define(cap i)(set! i(string-append i))(define c(string-ref i 0))(string-set! i 0(if(char-upper-case? c)c(integer->char(-(char->integer c)32))))i)
(let*((ex(list"a""an""the""at""by""for""in""of""on""to""up""and""as""but""or""and""nor"))(sl(string-split s)))
(string-join(for/list((i sl)(n(in-naturals)))(cond[(= n 0)(cap i)][(member i ex)i][(cap i)]))))

Ungolfed:
(define (f s)

  (define (cap i)                 ; sub-fn to capitalize first letter of a word
    (set! i (string-append i))
    (define c (string-ref i 0))
    (string-set! i 0
                 (if (char-upper-case? c)
                     c
                     (integer->char (-(char->integer c)32))))
    i)

  (let* ((ex (list "a""an""the""at""by""for""in""of""on""to""up""and""as""but""or""and""nor"))
         (sl (string-split s)))
    (string-join
     (for/list
         ((i sl)
          (n (in-naturals)))
       (cond
         [(= n 0) (cap i)]
         [(member i ex) i]
         [(cap i)]
         )))))

Testing:
(f "the rule of thumb for title capitalization")

Output:
"The Rule of Thumb for Title Capitalization"

C#, 305 bytes
Lots of room for improvement still but here you go:
s=>{;var b=s.Split(' ');b[0]=((char)(b[0][0]-32))+b[0].Substring(1);int i=0,n=b.Length;for(;++i<n;)if(!"a,an,the,at,by,for,in,of,on,to,up,and,as,but,or,nor".Split(',').Contains(b[i]))b[i]=((char)(b[i][0]-32))+b[i].Substring(1);b[n-1]=((char)(b[n-1][0]-32))+b[n-1].Substring(1);return string.Join(" ",b);};

PHP, 109 142 bytes
<?=preg_replace_callback("# (A[snt]?|And|[FN]or|Up|By|But|The|To|In|O[rnf])(?= )#",function($m){return strtolower($m[0]);},ucwords($argv[1]));

A merger of user59178´s and mbomb007´s answer.
uppercases the first letter of every word, then lowercases all words from the list surrounded by spaces.
Unfortunately, the callback has to operate on the complete set; this costs 29 bytes.

it works not for a an and as at but by for in nor of on or the to up

Ruby, 123 117 111 102 bytes
->s{s.gsub(/ .|^./,&:upcase).gsub(/ (A[nts]?|The|By|In|To|Up|And|But|[NF]or|O[rnf])(?= )/,&:downcase)}

Sorry for all the edits - this should be the last one.

Pure bash - 253
(no external programs called) - needs bash v4
declare -A b;for x in A An The At By For In Of On To Up And As But Or Nor;do b[$x]=1;done
while read -a w;do
n=${#w[@]};o[0]=${w[0]^}
for((i=1;i<n-1;i++)){
g=${w[$i]^};((${b[$g]}))&&o+=(${g,,})||o+=($g);}
((n>1))&&o[$n]=${w[-1]^}
echo ${o[@]};o=()
done

normal view with comments
#create the "blacklist"
declare -A b
for w in A An The At By For In Of On To Up And As But Or Nor
do
    b[$x]=1
done

# logic:
# read each line (split by words) into array
# and each word is assigned capitalized to the new output array
# but the blacklisted ones

#read each line to array w (split on spaces)
while read -a w
do
    n=${#w[@]}         # get the number of words
    o[0]=${w[0]^}          # copy the capitalized word1
    for((i=1 ; i<n-1 ; i++)) { # loop over 2 up to last -1 words

        g=${w[$i]^}    # for the given word
        # check if it is in the blacklisted ones
        # if yes - convert to lowercase, if not leave as it is
        # and append to the output array
        (( ${b[$g]} )) && o+=(${g,,}) || o+=($g)
    }
    # capitalize the last word if here is more words
    (( n>1 )) && o[$n]=${w[-1]^}
    # make a line from the words
    echo ${o[@]}
    o=() #cleanup
done

output
Title
And and And
The Rule of Thumb for Title Capitalization
Programming Puzzles and Code Golf
The Many Uses of the Letter A
A an and as at but by for in nor of on or the to Up
On Computable Numbers With an Application to the Entscheidungsproblem

Japt, 71 bytes
£`a  e  by f     up d  ¿t  n`¸aX >0©Y¦0©YÄ¦Zl ?X:Xg u +XÅ}S

Try it online!
Explanation:
£`a  e  by f     up d  ¿t  n`¸aX >0©Y¦0©YÄ¦Zl ?X:Xg u +XÅ}S
£`...`qS aX >0&&Y!=0&&Y!=UqS l -1?X:Xg u +Xs1}S

£                                            }S   // Split at spaces and map each item X by this function:
 `...`                                            //  Backticks are used to decompress strings
      qS                                          //  Split the decompressed string at spaces.
         aX >J                                    //  If this contains X
              &&Y!=0                              //  and the index is non-zero (it's not the first word)
                    &&Y!=UqS l -1                 //  and the index is not the length of the input -1 (it's not the last word),
                                 ?X               //  return X.
                                   :Xg u +Xs1     //  Else, return X capitalized. (Literally X[0].toUpperCase() + X.slice(1))
                                             }S   // Rejoin with spaces

One of my favorite Japt features is its string compression, which uses the shoco library.
You can compress a string by wrapping it in Oc"{string}" → Oc"a an the at by for in of on to up and as but or nor"
Then decompressing it with backticks or Od"{compressed string}" → Od"a  e  by f     up d  ¿t  n"

The -S flag was added after this challenge was posted, so your current solution is non-competing. However, I think you can do £...+XÅ}S, which would be competing for the same byte-count (Try it online!)

How does shoco compare with Jelly's dictionary compression in your opinion?

@RobertFraser Compared to Jelly, it's not very good at compressing strings of English words, but it is very good at compressing strings of arbitrary lowercase letters, which comes in handy sometimes.

Pure bash - 205 192 181 bytes
tc(){
while read -a x
do x=(${x[@]^})
for ((i=1;i<${#x[@]}-1;i++))
do
case "${x[i]}" in
A|A[nts]|The|By|[FN]or|In|O[fnr]|To|Up|And|But)x[i]=${x[i],};;
esac
done
echo ${x[@]}
done
}

Like jm66's answer tc accepts standard input.

Actually, 79 bytes
' ,ÿsd@p@`;0"A0An0The0At0By0For0In0Of0On0To0Up0And0As0But0Or0Nor"síu'ù*ƒ`Moq' j

Try it online!
Explanation:
' ,ÿsd@p@`;0"longstring"síu'ù*ƒ`Moq' j
' ,ÿs                                   title case input, split on spaces
     d@p@                               pop first and last words to stack
         `;0"longstring"síu'ù*ƒ`M       for every word except the first and last:
          ;0"longstring"s                 duplicate word, split the long string on 0s
                         íu               1-based index of word in list (0 if not found)
                           'ù*            "ù"*(index)
                              ƒ           execute the resulting string as a function (lowercases word if it's in the list)
                                 oq' j  put the first and last word back in the list, join with spaces

Batch, 323 bytes
@echo off
set s=
for %%w in (@%*@)do call:w %%w
echo%s%
exit/b
:w
for %%s in (a an the at by for in of on to up and as but or nor)do if %%s==%1 set s=%s% %1&exit/b
set w=%1
set w=%w:@=%
set f=%w:~0,1%
for %%c in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)do call set f=%%f:%%c=%%c%%
set s=%s% %f%%w:~1%

With comments:
@echo off
rem Start with an empty output string
set s=
rem Wrap the parameters in @ signs to identify the first and last words
for %%w in (@%*@) do call :w %%w
rem Ignore the leading space when printing the result
echo%s%
exit/b
:w
rem Check whether this is a word that we don't change
for %%s in (a an the at by for in of on to up and as but or nor) do if %%s==%1 set s=%s% %1&exit/b
set w=%1
rem Delete any @ signs from the first and last words
set w=%w:@=%
rem Get the first character
set f=%w:~0,1%
rem Case insensitively replace each upper case letter with itself
for %%c in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do call set f=%%f:%%c=%%c%%
rem Concatenate with the rest of the word
set s=%s% %f%%w:~1%

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Perform several mathematic operations
The task:
You have to input 2 numbers and output the results of several operations done with them.
Details:
Input 2 floating point numbers, x != 0 and y != 0 via stdin, command line or function arguments.
Output x+y,
       x*y,
       x^y (pow(x,y), not x XOR y),
       x-y,
       y-x,
       x/y and
       y/x on STDOUT separated by newlines, commas or spaces.
For languages which doesn't support floats, you may use an external library, implement them yourself or you can not participate :(
Standard loopholes apply, the shortest code in bytes wins. Good luck!

You want us to print the results of each?

@jacksonecac Yes.

What is unclear about this, please?

And if it's still unclear, how could I do it better?

Please specify what operations these are. Is x^y XOR or exponentiation?

Uh, if that's the problem... Fixed in 1 min.

@DmitryKudriavtsev: No, the linked challenge is about one integer changed with commands, and this is about two floats which are involved in several calculations. Still thanks for the tip :)

@MegaMan You have to realize, that's the same in many languages. So this is still a duplicate.

@mbomb007 It's still a difference. In the linked question you have to enter the commands, which isn't the case here. I can understand you, but this is not the same.

@MegaMan If parsing is the only difference, it's too similar.

@mbomb007 well, on the accumulator you can only add 1, substract 1, multiply by 2 and divide by 2. I think that's a big difference...

Dyalog APL, 15 bytes
Takes x as left argument and y as right argument.
+,×,*,-,-⍨,÷,÷⍨

Simply a long train of forks (3-trains):
+, the sum, followed by
×, the product, followed by
*, the exponentiation, followed by
-, the difference, followed by
-⍨, the swapped difference, followed by
÷, the ratio, followed by
÷⍨ the swapped ratio
TryAPL online!

Haskell, 44 bytes
x#y=mapM print[x+y,x*y,x**y,x-y,y-x,x/y,y/x]

Example: 4 # 5 prints
9.0
20.0
1024.0
-1.0
1.0
0.8
1.25

Ruby, 40 bytes
->x,y{puts x+y,x*y,x**y,x-y,y-x,x/y,y/x}

Scala, 68 bytes
(x:Float,y:Float)=>Seq(x+y,x*y,math.pow(x,y),x-y,x/y,y/x)map println

Pretty striaghtforward.

Groovy, 36 bytes
{a,b->print([a+b,a-b,a/b,a*b,a**b])}

Output:
({a,b->print([a+b,a-b,a/b,a*b,a**b])})(5.034,2.0568)

Results in:
[7.0908, 2.9772, 2.4474912485, 10.3539312, 27.777623862468822]

J, 15 bytes
Equivalent to this.
Takes x as left argument and y as right argument.
+,*,^,-,-~,%,%~

Simply a long train of forks (3-trains):
+, the sum, followed by
*, the product, followed by
^, the exponentiation, followed by
-, the difference, followed by
-~, the swapped difference, followed by
%, the ratio, followed by
%~ the swapped ratio

PowerShell v2+, 66 bytes
param($x,$y)$x+$y;$x*$y;[math]::Pow($x,$y);$x-$y;$y-$x;$x/$y;$y/$x

Very boring, does exactly what it says on the tin. Each statement (separated by ;) is evaluated and left on the pipeline. At program completion, everything left on the pipeline is implicitly printed via Write-Output.
Long because PowerShell uses $ to delineate variables, and it also doesn't have a ^ or ** or equivalent operator, so we need a .NET call.
Note that the Write-Output will display as integer values, even if the input is floats. Running a .GetType() will show the output to be System.Double however.
PS C:\Tools\Scripts\golfing> .\perform-several-mathematic-operations.ps1 5.0 6.0
11
30
15625
-1
1
0.833333333333333
1.2

C# - 106 bytes
void r(float x,float y){System.Console.WriteLine($"{x+y} {x*y} {Math.Pow(x,y)} {x-y} {y-x} {x/y} {y/x}");}


text:
The Last Monday
Monday, October 31st, is Halloween. And it got me thinking -- I wonder what other months have the last day of the month also be a Monday?
Input

A positive integer in any convenient format representing a year, 10000 > y > 0.
The input can be padded with zeros (e.g., 0025 for year 25) if
required.

Output

A list of the months of that year where the last day of the month is a Monday.
This can be as month names (e.g., January, March, October), or shortnames (Jan, Mar, Oct), or numbers (1, 3, 10), as separate lines or a list or delimited, etc., just so long as it's unambiguous to the reader.
The output format must be consistent:

For all years input (meaning, you can't output month names for some inputs, and month numbers for other inputs)
As well as consistent per output (meaning, you can't output 1 for January in the same output as Jul for July)
Basically, pick one format and stick to it.

Rules

Assume the Gregorian calendar for input/output, even down to y = 1.
Leap years must be properly accounted for (as a reminder: every year divisible by 4, except not years divisible by 100, unless also divisible by 400 -- 1700, 1800, 1900 all weren't leap years, but 2000 was).
You may use any built-ins or other date calculation tools you like.
Either a full program or a function are acceptable. If a function, you can return the output rather than printing it.
Standard loopholes are forbidden.
This is code-golf so all usual golfing rules apply, and the shortest code (in bytes) wins.

Examples
   1 --> Apr, Dec
 297 --> May
1776 --> Sep
2000 --> Jan, Jul
2016 --> Feb, Oct
3385 --> Jan, Feb, Oct

Leaderboard

var QUESTION_ID=97585,OVERRIDE_USER=42963;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="
"+e.body.replace(OVERRIDE_REG,"")+"
")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
 <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">

Leaderboard

	Author	Language	Size

Winners by Language

Language	User	Score

{{PLACE}}	{{NAME}}	{{LANGUAGE}}	{{SIZE}}	Link

{{LANGUAGE}}	{{NAME}}	{{SIZE}}	Link

Related 1 and Related 2.

Related but not duplicates or?

@ElPedro Related but not duplicates. The first does not allow any built-ins and asks for a fixed date/day combo (Friday the 13th), while the second asks for the last Sunday of every month of the year, limited between 1900 to 3015.

Sorry @TimmD. My misunderstanding of your comment.

@ElPedro No problem! I would rather have a question and have it be clear, than to not have a question and have something unclear.

Can we print the months as YearMonth, for instance 2016-02 2016-10?

@OlivierGrégoire Sure, that's fine, so long as it's consistent.

Can we return an array with falsy values in place of non-Monday months (e.g. [0,2,0,0,0,0,0,0,0,10,0,0])? There's a JS ES6 answer that currently does this.

@ETHproductions Yeah, that's fine, since it's still unambiguous to the reader. The output formatting isn't the interesting part of this challenge.

Dyalog APL with dfns's cal, Version 15.0: 22; Version 16.0: 19 bytes
The cal function comes with a default install, just enter )copy dfns.
Version 15.0: ∊⎕{⍵/⍨2=≢⍎⊢⌿cal⍺⍵}¨⍳12
∊ enlist (flatten)
⎕{...}¨ numeric input as left argument to the following anonymous function, taking each of the right side values as right argument in turn
 ⍵/⍨ the argument if (gives an empty list if not)
 2= two (namely Sunday and Monday) is equal to
 ≢ the tally of
 ⍎ the numbers in
 ⊢⌿ the bottom-most row of
 cal the calendar for
 ⍺⍵ year left-argument, month right-argument, the latter being
⍳12 1 to 12
Version 16.0: ⍸2=⎕{≢⍎⊢⌿cal⍺⍵}¨⍳12
⍸ the indices where
2= two equals (namely Sunday and Monday)
⎕{...}¨ numeric input as left argument to the following anonymous function, taking each of the right side values as right argument in turn
 ≢ the tally of
 ⍎ the numbers in
 ⊢⌿ the bottom-most row of
 cal the calendar for
 ⍺⍵ year left-argument, month right-argument, the latter being
⍳12 1 to 12

JavaScript (Firefox 30+), 112 109 103 95 bytes
Look ma, no built-ins!
y=>[for(m of(i=0,y%4|y%400*!(y%100)&&6)+"63153042641")if((i++,y+(y>>2)-(y/100|0)*3/4|0)%7==m)i]

Here's a 107-byte ES6 version:
y=>[...(y%4|y%400*!(y%100)&&6)+"63153042641"].map((m,i)=>(y+(y>>2)-(y/100|0)*3/4|0)%7-m?0:i+1).filter(x=>x)

And here's my previous attempt, 123 113 bytes of ES6:
y=>[(l=y%4|y%400*!(y%100))?[7]:[1,7],[4,12],[9],[3,6],[8,11],[5],l?[1,2,10]:[2,10]][(y+(y>>2)-(y/100|0)*3/4|0)%7]

Explanation
The day of the week of a particular year is calculated like so:
y+(y>>2)-(y/100|0)*3/4|0)%7

In other words:

Take y.
Add the number of 4th years before y (y>>2).
Subtract the number of 100th years before y (y/100|0).
Add back in the number of 400th years before y; this is 1/4 of y/100|0, so we use *3/4|0.

Then we modulo the result by 7. If we let 0 mean Sunday, 1 mean Monday, etc., the result corresponds to the day of the week of December 31st of that year. Therefore, for December, we want to check if the result is 1. This gives us the last char in the string.
The last day of November is 31 days before the last day of December. This means that for the last day of November to be a Monday, Dec 31 needs to be a (1 + 31) % 7 = 4 = Thursday.
This procedure is repeated until we get back to March (a 3). Whether or not there is a leap day, the last day of February is 31 days before the last day of March, so we can calculate that too (it's (3 + 31) % 7 = 6). The tricky part is finding the correct value for January:

If it is a leap year, the last day of January is 29 days before the last day of Feb, resulting in (6 + 29) % 7 = 0.
Otherwise, it is 28 days before the last day of Feb, resulting in (6 + 28) % 7 = 6.

We can calculate whether or not it is a leap year with the following snippet:
!(y%400)|y%100*!(y%4)

This gives 0 if y is not a leap year, and a positive integer otherwise. This leads us to
!(y%400)|y%100*!(y%4)?0:6

for calculating the day for January. However, we can do better by reversing the conditions:
y%4|y%400*!(y%100)?6:0

Since the falsy result is always 0 anyway, we can reduce it to
y%4|y%400*!(y%100)&&6

saving one more precious byte.
Putting it all together, we loop through each char in the string, checking if each is equal to the day of the week of Dec 31st. We keep the indexes of the ones that match, returning this array in the end. And that is how you do leap year calculations without built-ins.

Owww... My brain, did you account for leap years in alla that?

@carusocomputing That's what !(y%4)*y%100|!(y%400) is for. every year divisible by 4, except not years divisible by 100, unless also divisible by 400

Hopefully y+(y>>2)+(z=y/25>>2)+(z>>2) still saves you a byte.

@Neil Thanks, but I found a better way :-)

Nice; I saved 6 bytes on my Batch port using (y*5/4-(y/100)*3/4).

Make that 8 bytes - (y*5/4-y/100*3/4).

@Neil I was just going to ask if you could remove those parens ;-)

This is just magnificent! :)

JavaScript (Firefox 30-57), 67 65 64 63 61 bytes
y=>[for(_ of(m='')+1e11)if(new Date(y+400,++m).getDay()==2)m]

Saved 2 4 6 bytes thanks to @ETHproductions. Saved another byte by outputting the months in reverse order.

I think you can save 2 bytes by winging it without .keys(): y=>[for(_ of(m=0,Array(12)))if(new Date(y+400,++m).getDay()==2)m]

@ETHproductions I can save a further byte by reversing the order!

Reverse order is fine. Formatting the output isn't the interesting part of this challenge.

What's our policy on Array Comprehensions now that they've been removed from the spec?

You can save another 2 bytes by skipping Array(12) altogether:  y=>[for(_ of(m=0,1e11+""))if(new Date(y+400,++m).getDay()==2)m]

@MayorMonty I believe the policy is that since they still work in Firefox 30+, they are still a valid feature.

BTW, I count 64 bytes in your current solution. (My suggestion is 63)

@ETHproductions Ah, all my byte counts are off by 1 for some reason. I'll fix that later.

Switch it around to save the parens: for(_ of(m="")+1e11)

@ETHproductions Bah, why didn't you just say so in the first place...

@Neil I hadn't thought of using 1e11+(m="") ;)

MySQL, 183 134 129 106 bytes
SET @y=2016;SELECT help_topic_id AS m FROM mysql.help_topic HAVING m BETWEEN 1 AND 12 AND 2=DAYOFWEEK(LAST_DAY(CONCAT(@y,-m,-1)))

Replace 2016 with the desired year. Run.
Rev. 2: Used the help_topics table in the default installation instead of creating a temporary table.
Rev.3: Adopted aross´s - trick and noticed I can also omit the quotes for "-1".
However, -1 is required in MySQL: I need a full date.
Rev.4: Restriction m BETWEEN 1 AND 12 could be done as m>0 AND m<13 (-6), but is not needed at all - invalid values will be ignored; warnings will be counted but not listed.

You need really the table shema mysql? https://mariadb.com/kb/en/mariadb/mysqlhelp_topic-table/

@JörgHülsermann I don´t get your point.

Should FROM help_topic without mysql. work? I have try it not

@JörgHülsermann only if you prepend USE mysql; The correct database must be selected somehow.

will this work for year 999 and earlier ?

@t-clausen.dk From the MySQL manual: The supported range is '1000-01-01' to '9999-12-31'.  I would add that to the description; but I am reluctant to edit a four year old post.

oh, I missed that part about being 4 years old. I fully understand.

Batch, 160 152 bytes
@set/ay=%1,m=0,j=6*!(!(y%%4)*(y%%100)+(y%%400)),y=(y*5/4-y/100*3/4)%%7
@for %%d in (%j% 6 3 1 5 3 0 4 2 6 4 1)do @set/am+=1&if %%d==%y% call echo %%m%%

Port of @ETHproduction's answer. With month abbreviations for 197 189 bytes:
@set/ay=%1,j=6*!(!(y%%4)*(y%%100)+(y%%400)),y=(y*5/4-y/100*3/4)%%7
@for %%m in (Jan.%j% Feb.6 Mar.3 Apr.1 May.5 Jun.3 Jul.0 Aug.4 Sep.2 Oct.6 Nov.4 Dec.1)do @if %%~xm==.%y% call echo %%~nm

Perl+cal, 46 bytes
say`cal $_ $ARGV[0]`=~/\n.{5}\n/&&$_ for 1..12

Example:
$ perl -E 'say`cal $_ $ARGV[0]`=~/\n.{5}\n/&&$_ for 1..12' 2016

2

10

$

Strictly speaking, this is perl + cal, not just perl :-p. For example, my Windows machine has perl, but this won't work there.

Fair point, updated this and my bash attempt.

Perl, 64 bytes
Includes +1 for -n
Give input on STDIN:
perl -M5.010 mon.pl <<< 2016

mon.pl:
#!/usr/bin/perl -n
map$b.=$/.gmtime$_.e4,-7e6..3e7;say$b=~/on (\S+ )\S.* $_.* 1 /g

Mathematica, 62 57 bytes
DayName@DayRange[{#},{#+1},"EndOfMonth"]~Position~Monday&

Anonymous function. Takes a number as input and returns a list of single-element lists of numbers as output. I'm honestly not sure myself how it works anymore.

J, 48 34 33 bytes
[:I.(2=7|_2#@".@,@{.])&>@calendar

Saved 15 bytes with help from @Adám.
Uses the calendar builtin to generate an array of strings representing the months, then parses each string to determine the whether the last Monday is the last day of the month. It outputs each month as the month number of each. That is, Jan = 0, Feb = 1, ..., Dec = 11.
The output of calendar is
   _3 ]\ calendar 2016
┌─────────────────────┬─────────────────────┬─────────────────────┐
│         Jan         │         Feb         │         Mar         │
│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│
│                 1  2│     1  2  3  4  5  6│        1  2  3  4  5│
│  3  4  5  6  7  8  9│  7  8  9 10 11 12 13│  6  7  8  9 10 11 12│
│ 10 11 12 13 14 15 16│ 14 15 16 17 18 19 20│ 13 14 15 16 17 18 19│
│ 17 18 19 20 21 22 23│ 21 22 23 24 25 26 27│ 20 21 22 23 24 25 26│
│ 24 25 26 27 28 29 30│ 28 29               │ 27 28 29 30 31      │
│ 31                  │                     │                     │
├─────────────────────┼─────────────────────┼─────────────────────┤
│         Apr         │         May         │         Jun         │
│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│
│                 1  2│  1  2  3  4  5  6  7│           1  2  3  4│
│  3  4  5  6  7  8  9│  8  9 10 11 12 13 14│  5  6  7  8  9 10 11│
│ 10 11 12 13 14 15 16│ 15 16 17 18 19 20 21│ 12 13 14 15 16 17 18│
│ 17 18 19 20 21 22 23│ 22 23 24 25 26 27 28│ 19 20 21 22 23 24 25│
│ 24 25 26 27 28 29 30│ 29 30 31            │ 26 27 28 29 30      │
│                     │                     │                     │
├─────────────────────┼─────────────────────┼─────────────────────┤
│         Jul         │         Aug         │         Sep         │
│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│
│                 1  2│     1  2  3  4  5  6│              1  2  3│
│  3  4  5  6  7  8  9│  7  8  9 10 11 12 13│  4  5  6  7  8  9 10│
│ 10 11 12 13 14 15 16│ 14 15 16 17 18 19 20│ 11 12 13 14 15 16 17│
│ 17 18 19 20 21 22 23│ 21 22 23 24 25 26 27│ 18 19 20 21 22 23 24│
│ 24 25 26 27 28 29 30│ 28 29 30 31         │ 25 26 27 28 29 30   │
│ 31                  │                     │                     │
├─────────────────────┼─────────────────────┼─────────────────────┤
│         Oct         │         Nov         │         Dec         │
│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│ Su Mo Tu We Th Fr Sa│
│                    1│        1  2  3  4  5│              1  2  3│
│  2  3  4  5  6  7  8│  6  7  8  9 10 11 12│  4  5  6  7  8  9 10│
│  9 10 11 12 13 14 15│ 13 14 15 16 17 18 19│ 11 12 13 14 15 16 17│
│ 16 17 18 19 20 21 22│ 20 21 22 23 24 25 26│ 18 19 20 21 22 23 24│
│ 23 24 25 26 27 28 29│ 27 28 29 30         │ 25 26 27 28 29 30 31│
│ 30 31               │                     │                     │
└─────────────────────┴─────────────────────┴─────────────────────┘

Usage
   f =: [:I.(2=7|_2#@".@,@{.])&>@calendar
   f 1
3 11
   f 297
4
   f 1776
8
   f 2000
0 6
   f 2016
1 9
   f 3385
0 1 9

Explanation
[:I.(2=7|_2#@".@,@{.])&>@calendar  Input: year Y
                         calendar  Get 12 boxes each containing a month
    (                )&>@          Operate on each box
                    ]                Identity, get the box
         _2       {.                 Take the last two strings
                ,@                   Flatten it
             ".@                     Parse it into an array of integers
           #@                        Get the length
       7|                            Take it modulo 7
     2=                              Test if it equals 2 - it will either
                                     have two days or 9 days in the last
                                     two lines if the end is on a Monday
[:I.                               Return the indices containing a true value

wait, does calendar actually output ascii art?

@DestructibleWatermelon To be exact, the output format of calendar is an array of 12 boxes where each box contains a 2d array of characters

I don't even know how to do "each" in J, but this is already much shorter: I.7=;#&.>".&.>,&.>_2{.&.>calendar 2016 If you combine all the "under-open"s you should be able to get it pretty short.

@Adám Thanks, it uses a better method but it's not a verb in J. I think it will still help though

My intention was only to inspire. I know it isn't a verb.

@Adám Inspire you did :) I saved 14 bytes with that shorter logic

Can you not replace ##\ with I.?

Java 7 ,186 182 172   bytes
Thanks to kevin for saving 4 bytes
Thanks to @cliffroot for saving 10 bytes
int[]f(int n){int c=n-1,x=c*365+c/4+c/400-c/100,k=0,b[]={3,(n%4<1&n%100>0)|n%400<1?1:0,3,2,3,2,3,3,2,3,2,3},a[]=new int[12];for(int i:b)a[k++]=(x+=i+28)%7==1?1:0;return a;}

ungolfed
int[] f(int n) {
 int c=n-1,x=c*365+(c/4)+(c/400)-(c/100),k=0,
   b[] = {3,(n % 4 < 1 & n % 100 > 0) | n % 400 < 1 ? 1 : 0
                                     ,3,2,3,2,3,3,2,3,2,3},a = new int[ 12 ];

 if ( (n % 4 < 1 & n % 100 > 1) | n % 400 < 1 )
     b[ 1 ] = -1;
 for (int i : b)
    a[ k++ ] = (x += i + 28) % 7 == 1 ? 1 : 0;

return a;
     }

This version is provide by @cliffroot(168 bytes)
 static int[] f(int n) {
 int b = 13561787 | ( (n%4 < 1 & n%100 > 0) | n%400 < 1 ? 1 << 20 : 0 ),
           x = --n*365 + n/4 + n/400 - n/100,a[]=new int[12],k=0;
    while (k < 12)
    a[k++] = (x += (b >> 24 - k*2&3 ) + 28) % 7 == 1 ? 1 : 0;
  return a;   }
    }

output sample
1 1 0 0 0 0 0 0 0 1 0 0(for input 3385)

After I wrote my answer I knew calculating everything yourself would be shorter.. :) Btw, you can golf n%4==0 to n%4<1; n%400==0 to n%400<1 and int c=...;int[]b=...,a=... to int c=...,b[]=...,a[]=....

b and a can be defined in the int part like this: int ... ,b[]=...,a[]=...

@OlivierGrégoire You're 2 minutes too late. ;) @Numberknot and you can also change n%100!=0 to n%100>0.

Done @KevinCruijssen.

int[]f(int n){int x=--n*365+n/4+n/400-n++/100,k=0,b[]={1,(n%4<1&n%100>0)|n%400<1?-1:-2,1,0,1,0,1,1,0,1,0,1},a[]=new int[12];for(int i:b)a[k++]=(x+=i+30)%7==1?1:0;return a;} few bytes saved

can also change b to b[]={3,(n%4<1&n%100>0)|n%400<1?1:0,3,2,3,2,3,3,2,3,2,3} and i+30 to i+28 for 2 more bytes

and another 3 bytes int[]f(int n){int b=13561787|((n%4<1&n%100>0)|n%400<1?1<<20:0),x=--n*365+n/4+n/400-n/100,a[]=new int[12],k=0;while(k<12)a[k++]=(x+=(b>>24-k*2&3)+28)%7==1?1:0;return a;}

C, 119 bytes
t=1248700335,m;main(y){for(scanf("%d",&y),t+=y&3||y%25<1&&y&15;m++,(6+y+y/4-y/100+y/400+t)%7||printf("%d,",m),t;t/=7);}

This uses a table that contains the offset of the weekdays of the last day of every month for a leap year, encoded in a signed 32-bit word using base 7. If it is not a leap year we add 1 to the offset of January (as you can see y&3||y%25<1&&y&15 is used to check for years without leap days). Then we simply loop through every month and check if its last day is a Monday. Quite simple actually, no ugly hacks or tricks. Here it is slightly ungolfed:
t=1248700335,m;
main(y){
  for(
    scanf("%d",&y),t+=y&3||y%25<1&&y&15;
    m++,(6+y+y/4-y/100+y/400+t)%7||printf("%d,",m),t;
    t/=7
  );
}

I might revisit this to rewrite it as a function to save a few characters. The printf also takes up a little too much space...

The printf("%d, ", m) would print something as 1, or 2, 3, so there is always one ',' more... I prefer use only spaces

Indeed, I also prefer spaces in the output actually, but I usually write my golfed C solutions so that they don't need any whitespace, so I can just nuke all whitespace from my half-golfed version when I want to check my character count.

Python 2, 122 bytes
Ugh. Math with dates isn't as simple as I'd like.
from datetime import*
lambda y:[m+1for m in range(12)if(date(y,12,31)if m>10else(date(y,m+2,1)-timedelta(1))).weekday()<1]

Try it online
Same length:
from datetime import*
lambda y:[m-1for m in range(2,14)if(date(y,12,31)if m>12else(date(y,m,1)-timedelta(1))).weekday()<1]

I wasn't even going to try Python with this one. Nice effort.

You have to include the import statement in your bytecount.

@pppery Way to notice something in an old post. Fixed.

PHP, 109 180 159 bytes
for($z=$argv[1];$m++<12;)if(date(N,strtotime(sprintf("%04d-$m-",$z).cal_days_in_month(0,$m,$z)))<2)echo"$m,";

Outputs the provided year, not all of them (... always read the question)
Ignored notices (thanks Titus)
Change while to for as it's now a single year (again, thanks Titus)

Old 2
$z=0;while($z++<9999){$o=[];$m=0;while($m++<12)if(date("N",strtotime(sprintf("%04d-$m-","$z").cal_days_in_month(0,$m,$z)))<2)$o[]=$m;echo count($o)>0?"$z:".implode(",",$o)."
":"";}

Supports all years from dot to 10000, also got rid of an undefined var warning I wasn't aware of on one PC. Yes it's longer than the old version, but it's more robust.
Old 1
while($z++<9999){$o=[];$m=0;while($m++<12)if(date("N",strtotime("$z-$m-".cal_days_in_month(0,$m,$z)))<2)$o[]=$m;echo count($o)>0?"$z:".implode(",",$o)."
":"";}

If running on Windows or a 32bit system there will be the dreaded 2038 bug, but on a 64bit linux system it's fine.
I did attempt to use date("t"... which is meant to represent the last date of the given month, but the results didn't match those previously mentioned in this thread.

-2: "$z" needs no quotes
-7: ignore the notices (they not printed with default settings: do not init $z, no quotes for N)
-1: for instead of while
-43: take input as requested instead of looping through the years
-3: join instead of implode
-16: direct output: for($z=$argv[1];$m++<12;)if(date(N,strtotime(sprintf("%04d-$m-",$z).cal_days_in_month(0,$m,$z)))<2)echo"$m,";
+9 if you insist on having no trailing comma: echo$o=$o?",$m":$m;

Ahh misread the question! Thought it was for all years.. oops :B Thanks for the other suggestions as well, will get on them

MATL, 21 bytes
12:"G@QhO6(YO9XO77=?@

Months are displayed as numbers.
Try it online! Or verify all test cases.
Explanation
This uses date conversion builtin functions. For the given year it tests which months' last day is Monday.
Instead of explicitly specifying the last day of month k (which may be 28, 29, 30 or 31), we specify the 0-th day of month k+1, which is equivalent and does not depend on month or year.
12:      % Push [1 2 ... 12] (months)
"        % For each month k
  G      %   Push input
  @Q     %   Push k+1
  h      %   Concatenate
  O6(    %   Postpend four zeros. For example, for input 2016 and month k=1
         %   (first iteration) this gives [2016 2 0 0 0 0] (year, month, day,
         %   hour, min, sec). The 0-th day of month k+1 is the same as the
         %   last day of month k.
  YO     %   Convert the above 6-element date vector to date number
  9XO    %   Convert date number to date string with output format 9, which
         %   is weekday as a capital letter
  77=    %   Is it an 'M'?
  ?      %   If so
    @    %     Push current month (will be implicitly displayed)

Bash + GNU utilities, 56 bytes
seq -f1month-1day$1-%g-1 12|date -f- +%B%u|sed -n s/1//p

Appears to require date version 8.25.  The 8.23 version in Ideone doesn't cut it.

Excel, 537 bytes
Because – you know – Excel!
Takes input year in A1. Returns hexadecimal list of months; 1=January, C= December. Since each month is a single digit, no separator is needed.
=IF(2=WEEKDAY(EOMONTH(DATE(A1,1,1),0)),1,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,2,1),0)),2,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,3,1),0)),3,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,4,1),0)),4,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,5,1),0)),5,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,6,1),0)),6,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,7,1),0)),7,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,8,1),0)),8,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,9,1),0)),9,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,10,1),0)),"A","")&IF(2=WEEKDAY(EOMONTH(DATE(A1,11,1),0)),"B","")&IF(2=WEEKDAY(EOMONTH(DATE(A1,12,1),0)),"C","")

Example: A1 contains 2016. B1 contains the above formula, and displays as 2A, meaning February and October.

Excel, 428 97 96 bytes
Input in A1.  Output un-separated Hexadecimal values (January = 0, December = B)
=IF(2=WEEKDAY(DATE(A1+2000,1,31)),0,"")&CHOOSE(WEEKDAY(DATE(A1+2000,3,0)),4,19,6,"3B",8,25,"7A")

Added 10 bytes ("+2000") to allow handling of pre-1990 dates.
Saved 11 bytes thanks to @Engineer Toast.

First attempt (428 bytes), borrowing heavily from @Adám's solution.
=IF(2=WEEKDAY(DATE(A1,1,31)),1,"")&IF(2=WEEKDAY(EOMONTH(DATE(A1,2,1),0)),2,"")&IF(2=WEEKDAY(DATE(A1,3,31)),3,"")&IF(2=WEEKDAY(DATE(A1,4,30)),4,"")&IF(2=WEEKDAY(DATE(A1,5,31)),5,"")&IF(2=WEEKDAY(DATE(A1,6,30)),6,"")&IF(2=WEEKDAY(DATE(A1,7,31)),7,"")&IF(2=WEEKDAY(DATE(A1,8,31)),8,"")&IF(2=WEEKDAY(DATE(A1,9,30)),9,"")&IF(2=WEEKDAY(DATE(A1,10,31)),"A","")&IF(2=WEEKDAY(DATE(A1,11,30)),"B","")&IF(2=WEEKDAY(DATE(A1,12,31)),"C","")

How does this work on years earlier than 1900? The test case 297 -> May returns 6 with this formula. Shouldn't it be 4? 1776 gives 7A instead of just 8 for September.

If you get it to work, though, you can probably use Date(A1,3,0) instead of EOMONTH(DATE(A1,2,1),0)

PHP, 96 95 76 71 69 64 61 bytes
Note: year numbers must be padded to 4 chars, like 0070.
for(;13+$i-=1;)date(N,mktime(0,0,0,1-$i,0,$argn))-1||print$i;

Run like this:
echo 3385 | php -nR 'for(;13+$i-=1;)date(N,mktime(0,0,0,1-$i,0,$argn))-1||print$i;';echo
> -1-2-10

Explanation
Iterates from -1 to -12. Create date using mktime, day 0 (the last day of the previous month) and month 2..13. Format the date as day number, and if the result is 1, print the current number. The negative sign - is used as the delimiter.
The Millenium Bug Strikes Again!
Note that with this version, the range 0..100 is interpreted as 1970..2069. This is no problem for the range 0..69, as weeks have a pattern that repeats every 400 years (146097 days, exactly 20871 weeks), but for the range 70..99, 1900 is added to the year number, which is not a multiple of 400. To fix that problem JUST for 30 year numbers in a range of 10k, the simplest way is to add 400 to the year number to prevent the 2-digit interpretation (+4 bytes):
for(;13+$i-=1;)date(N,mktime(0,0,0,1-$i,0,$argn+400))-1||print$i;

Tweaks

Saved a byte by using !~-$i to compare $i with 1 (-1 binary negated is 0, logically negated is true; every other number is false), so parentheses aren't needed
Saved 19 bytes by using last day ofYYYY-m notation to create the date
Saved 5 bytes by using date and strtotime instead of date_create
Saved 2 bytes by counting from negative numbers, using the negative sign as output delimiter (negative month numbers don't exist) and also as delim in the YYYY-m part of the date
Saved 5 bytes by using mktime instead of strtotime. Reverted to using day 0 (mktime also supports month 13, so 0-13==31-12)
Saved 3 bytes by using -R to make $argn available

mktime removes the necessity to pad the year, doesn´t it?

@Titus, sharp. Well I just figured out that mktime is counter-intuitive, because the arguments are taken as INTs. That means you can't pad the year... so everything in range 0..100 is interpreted as 1970..2070. That is no problem for the range 0..70 because 400 years have an exact number of weeks (so calendars repeat the pattern every 400 years), but 70..99 adds 1900 (not a multiple of 400!). Therefore new ver. has a bug.

Only solution I see for that right now is$argv[1]+400 ... unless Julian and Gregorian weekdays differ.

@Titus, yep. Rules say use Gregorian cal

C, 214 bytes
main(int a,char *b[]){for(int x,y,d,m=12;m;m--){y=atoi(b[1]);x=m-1;d=x==1?(y%4==0?(y%100==0?(y%400==0?29:28):29):28):(x==3||x==5||x==10?30:31);if((d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7==1)printf("%d\n",m);}}

Compile
gcc -std=c99 -o foo foo.c

Ungolfed
With credits to the relevant gurus.
Michael Keith and Tom Craver for C Program to find day of week given date.
Collin Biedenkapp for Q&A: How do I figure out what the last day of the month is?
/* credit to Collin Biedenkapp */
short _get_max_day(short x, int z) {
    if(x == 0 || x == 2 || x == 4 || x == 6 || x == 7 || x == 9 || x == 11)
        return 31;
    else if(x == 3 || x == 5 || x == 8 || x == 10)
        return 30;
    else {
        if(z % 4 == 0) {
            if(z % 100 == 0) {
                if(z % 400 == 0)
                    return 29;
                return 28;
            }
            return 29;
        }
        return 28;
    }
}

main(int argc,char *argv[]) {
 for(int y,d,m=12;m;m--) {
  y=atoi(argv[1]);
  d=_get_max_day(m-1,y);
  /* credit to Michael Keith and Tom Craver */
  if ((d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7 == 1)
    printf("%d\n",m);
 }
}

What if you flip your if the other direction, to have your else return 31, and therefore you can eliminate the big == chain?

would be better if(x==1) {z part}else if(x==3|| x == 5 || x == 8 || x == 10)return 30 else return 31

what about: return  x==1?(z%4==0?(z%100==0?(z%400==0?29:28):29):28):(x==3||x==5||x==8||x==10?30:31)

TimmyD + RosLuP : thanks for the return() points, 100 bytes now saved.

it is possible continue to reduce at last until this: u(y,m){return m-1?30+((2773>>m)&1):28+(y%4==0&&y%100||y%400==0);} where y is the year and m the month

PHP, 92 Bytes
for($d=new DateTime("$argv[1]-1-1");$i++<12;)$d->modify("1month")->format(w)!=2?:print"$i,";

check 12 times 1 month after first day of a year is a tuesday. If it is then is the day before the last day in the month is a monday.

You could use echo instead of print and save 1

@Octopus not inside the ternary Operator

Bash+cal, 58 bytes
$ cat t.sh
for A in {1..12};do cal $A $1|grep -qx .....&&echo $A;done
$ bash t.sh 2016
2
10
$

+1 - works for BSD cal (e.g. OSX), but watch for trailing spaces on GNU cal.

Ruby, 54 + 6 = 60 bytes
λ cat monday.rb
p (1..12).select{|m|Date.new($*[0].to_i,m,-1).monday?}
λ ruby -rdate monday.rb 2016
[2, 10]

6 bytes for -rdate on the command line to get the Date class from the standard library.
Explanation: pretty straightforward thanks to the Ruby stdlib's great Date class. Not only does it have methods like monday?, tuesday?, etc, the constructor will take negative numbers for any field past year to mean 'count this field backwards from the end of the period represented by the previous field'. $* is shorthand for ARGV, so $*[0] is a quick way to get the first command line argument.

Python 2, 94 bytes
from datetime import*
lambda y:[m for m in range(1,13)if date(y+(m>11),m%12+1,1).weekday()==1]

repl.it
An unnamed function, takes an integer year, outputs a list of the month numbers [1-12].
I also tried to beat the byte count with arithmetic without success (110 bytes). :
lambda y:map(lambda x,v:(23*((x+2)%13or 1)/9+y-2*(0<x<11)+(x>10)+v/4-v/100+v/400)%7==4,range(12),[y-1]+[y]*11)

An unnamed function which returns a list of boolean values representing if the months [Jan-Dec] end in a Monday

Java 7, 200 249 bytes
import java.util.*;String c(int y){String r="";GregorianCalendar c=new GregorianCalendar();c.setGregorianChange(new Date(1L<<63));c.set(1,y);c.set(2,0);for(int i=0;i++<12;c.add(2,1)){c.set(5,c.getActualMaximum(5));if(c.get(7)==2)r+=i+" ";}return r;}

In Java, GregorianCalendar is a mix between a Gregorian and Julian calendar. Because of this, year 1 gave incorrect results. Changing Calendar c=Calendar.getInstance(); to GregorianCalendar c=new GregorianCalendar();c.setGregorianChange(new Date(1L<<63)); fixes this by forcing a use of the Gregorian calendar only. Thanks to @JonSkeet on stackoverflow.com for explaining this to me.
Ungolfed & test code:
Try it here.
import java.util.*;
class M{
  static String c(int year){
    String r = "";
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setGregorianChange(new Date(Long.MIN_VALUE));
    calendar.set(Calendar.YEAR, year);
    calendar.set(Calendar.MONTH, 0);
    for(int i = 0; i++ < 12; calendar.add(Calendar.MONTH, 1)){
      calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
      if(calendar.get(Calendar.DAY_OF_WEEK) == 2){
        r += i+" ";
      }
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c(1));
    System.out.println(c(297));
    System.out.println(c(1776));
    System.out.println(c(2000));
    System.out.println(c(2016));
    System.out.println(c(3385));
  }
}

Output:
4 12
5
9
1 7
2 10
1 2 10

R, 106 99 95 83 78 77 74 bytes
g=function(x)which(format(seq(as.Date(paste0(x,-2,-1)),,'m',12)-1,"%u")<2)

The sequence of last days of each month is given by seq(as.Date(paste0(x,-2,-1)),,'m',12)-1:

paste0 coerces -2 and -1 to characters. If the x was 2016 for instance, paste0(x,-2,-1) gives "2016-2-1" which is then converted to the 1st of February 2016 by as.Date.

seq applied to a POSIXct or a Date object is seq(from, to , by, length.out): here to is not given, by is given as 'm' which is matched to 'month' thanks to partial matching, and length.out is of course 12.

The resulting sequence is the first day of the 12 months starting with February of the year in question. -1 gives us then the last day of the 12 months starting with January of the year in question.

Test cases:
> g(1)
[1]  4 12
> g(25)
[1] 3 6
> g(297)
[1] 5
> g(2000)
[1] 1 7
> g(2016)
[1]  2 10
> g(3385)
[1]  1  2 10
> g(9999)
[1] 5

Old version at 95 bytes, outputting the month names instead of just their numbers:
g=function(x)format(S<-seq(as.Date(sprintf("%04i-02-01",x)),,'m',12)-1,"%B")[format(S,"%u")==1]

This answer is just brilliant. I had no idea seq had a method for Date -objects and this solves the issue of as.Date not handling years above 10000 in my deleted answer.

@Billywob yes seq.Date and seq.POSIXt are quite impressive: they can even process commands such as seq(time1, time2, by="10 min") or seq(date1, date2, by="quarter"). Very useful when plotting a time-series.

C#6 C#, 171 167 135 bytes
using System;
void d(int n){for(int i=0;++i<13;)if((int)new DateTime(n,i,DateTime.DaysInMonth(n,i)).DayOfWeek==1)Console.Write(i+" ");}

-32 bytes thanks to Shebang
Print months as numbers; with space delimited; with trailing space. Now this answer also works for earlier versions of C#.

Old, 167 bytes
using System;using System.Linq;
c(int n)=>string.Join(",",Enumerable.Range(1,12).Where(i=>new DateTime(n,i,DateTime.DaysInMonth(n,i)).DayOfWeek==(DayOfWeek)1));

-4 bytes thanks to TimmyD
Output months are numbers in return string, comma delimited
Ungolfed
string c(int n)=>
    string.Join(",",                                        // Join them with commas
        Enumerable.Range(1,12)                              // For 1-12 inclusive
        .Where(                                             // Select only
            i=>new DateTime(n,i,DateTime.DaysInMonth(n,i)   // Get last day of that year-month
            ).DayOfWeek                                     // Get its day of week
            ==(DayOfWeek)1                              // Is Monday
        )
    )
;

@TimmyD Yes but need explicit cast. Answer updated

LINQ is fun but this is 126 bytes: void q(int y){for(int m=1;m<13;m++){if((int)new DateTime(y,m,DateTime.DaysInMonth(y,m)).DayOfWeek==1){Console.WriteLine(m);}}} ;) Also, it would be shorter to cast the DayOfWeek to int than it would be to cast the int to DayOfWeek

@Shebang Thanks. I really shouldn't golf in one-line linq --- Only Jon Skeet can do that. See if I have time for update tomorrow. Tired now.

You can convert this to be an Action<int> to save some bytes

Japt, 24 bytes
Do1 £Ov"Ð400+U"+X e ¥2©X

Test it online! Outputs an array of numbers, with false in place of months that don't end in a Monday.
There was a bug in the interpreter that didn't allow me to use Ð in the function body £. After the bug fix and another feature addition, this is 18 bytes in the current commit:
Do1@Ð400+UX e ¥2©X

Java, 143 129 bytes
This uses the new time API of Java 8.
y->{String s="";for(int m=0;++m<13;)if(java.time.YearMonth.of(y,m).atEndOfMonth().getDayOfWeek().ordinal()==0)s+=m+" ";return s;}

Output
Note that each line has an extra space at the end.
4 12
5
9
1 7
2 10
1 2 10

Ungolfed and testing
import java.time.*;
import java.util.function.*;

public class Main {
    public static void main (String[] args) {
        IntFunction<String> func = year -> {
          String result = "";
          for (int month=1; month <= 12; month++) {
            if (YearMonth.of(year, month).atEndOfMonth().getDayOfWeek().ordinal() == 0) {
              result += month + " ";
            }
          }
          return result;
        };
        System.out.println(func.apply(1));
        System.out.println(func.apply(297));
        System.out.println(func.apply(1776));
        System.out.println(func.apply(2000));
        System.out.println(func.apply(2016));
        System.out.println(func.apply(3385));
    }
}

Shaves

143 to 129 bytes: use DayOfWeek::ordinal to compare with a numerical constant instead of the enum constant.Thanks @TimmyD for the general idea if not the exact solution! ;-)

@TimmyD sadly, it's an enum. It does have a getValue() method, though, which would save a few bytes.

@Celos ordinal() saves 1 more byte compared to getValue(), even though it is suggested to never use it.

yes, good thinking. I posted my comment without first refreshing, so I didn't see your reply and edit.

GNU awk, 80 bytes
{for(;m<13;a=mktime($0" "++m" 1 9 0 0")){if(strftime("%w",a-8e4)~1){print m-1}}}

Example
$ gawk '{for(;m<13;a=mktime($0" "++m" 1 9 0 0")){if(strftime("%w",a-8e4)~1){print m-1}}}' <<<2016
2
10
$

PHP, 109 bytes
$y=$argv[1];for($i;++$i<13;)echo(date('N',strtotime($y."-$i-".date('t',strtotime("$y-$i-1"))))==1?"$i ":'');

The code produces a notice due to for($i; but the question mentions nothing about avoiding errors.

Outputs months numbers separated by a space.

   1 --> 1 12
 297 --> 5
1776 --> 9
2000 --> 1 7
2016 --> 2 10
3385 --> 1 2 10

Works in PHP 5.2.16 and onward at http://sandbox.onlinephpfunctions.com/

STDERR is ignored by default, so this is fine.

JavaScript, 65 bytes
v=>[...""+1e11].map((x,i)=>new Date(v+400,++i).getDay()==2?i:"")

Stealing the ""+1e11 trick from the other JavaScript answer.
Returns ["", 2, "", "", "", "", "", "", "", 10, "", ""] for 2016, indicating that Feb and Oct end on a Monday.
Edited: Years 0-99 are parsed as 1900-1999 in JS.  Adding 400 causes them to be parsed as 400-499, which are equivalent calendar years.

C, 175 217 bytes
#define R return
#define L(i) for(;i-->0;)
u(y,m){R m-1?30+((2773>>m)&1):28+(y%4==0&&y%100||y%400==0);}s(y,m,g){g+=4;L(m)g+=u(y,m),g%=7;L(y)g+=1+u(y,1),g%=7;R g;}w(y,m,r){m=12;L(m)s(y,m,u(y,m))||(r|=1<<(m+1));R r;}

Code for to find the last day for febrary taken from K&R2 try http://ideone.com/XtuhGj the function for debug is w
z(y,m,r){m=12;L(m)s(y,m,13)-4||(r|=1<<(m+1));R r;}

/*
// ritorna il numero dei giorni di anno=y mese=m con mese in 0..11
// m==1 significa febbraio   y%4?0:y%100?1:!(y%400) non funziona
u(y,m){R m-1?30+((2773>>m)&1):28+(y%4==0&&y%100||y%400==0);}

// argomenti anno:y[0..0xFFFFFFF]  mese:m[0..11]  giorno:g[1..u(y,m)]
// ritorna il numero del giorno[0..6]
s(y,m,g)
{g+=4; // correzione per il giorno di partenza anno mese giorno = 0,1,1
 L(m)g+=  u(y,m),g%=7; // m:0..m-1  somma mod 7 i giorni del mese dell'anno y
 L(y)g+=1+u(y,1),g%=7; // y:0..y-1  somma mod 7 gli anni da 0..y-1
                       // g+=1+u(y,1) poiche' (365-28)%7=1 e 1 e' febbraio
 R g;
}

// argomenti anno:y[0..0xFFFFFFF], m=0 r=0
// calcola tutti gli ultimi giorni del mese dell'anno y che cadono di lunedi'
// e mette tali mesi come bit, dal bit 1 al bit 12 [il bit 0 sempre 0] in r
w(y,m,r){m=12;L(m)s(y,m,u(y,m))||(r|=1<<(m+1));R r;}

// argomenti anno:y[0..0xFFFFFFF], m=0 r=0
//ritorna in r il numero dei mesi che ha giorno 13 di venerdi[==4]
// e mette tali mesi come bit, dal bit 1 al bit 12 [il bit 0 sempre 0] in r
z(y,m,r){m=12;L(m)s(y,m,13)-4||(r|=1<<(m+1));R r;}
*/

#define P printf
#define W while
#define M main
#define F for
#define U unsigned
#define N int
#define B break
#define I if
#define J(a,b)  if(a)goto b
#define G goto
#define P printf
#define D double
#define C unsigned char
#define A getchar()
#define O putchar
#define Y malloc
#define Z free
#define S sizeof
#define T struct
#define E else
#define Q static
#define X continue
M()
{N y,m,g,r,arr[]={1,297,1776,2000,2016,3385}, arr1[]={2016,1,1997,1337,123456789};
 C*mese[]={"gen","feb","mar","apr","mag","giu","lug","ago","set","ott","nov","dic"};
 C*giorno[]={"Lun","Mar","Mer","Gio","Ven","Sab","Dom"};
 P("Inserisci Anno mese giorno>");r=scanf("%d %d %d", &y, &m, &g);
 P("Inseriti> %d %d %d r=%d\n", y, m, g, r);
 I(r!=3||m>12||m<=0||g>u(y,m-1))R 0;
 r=s(y,m-1,g);// 12-> 11 -> 0..10
 P("Risultato=%d giorno=%s\n", r, giorno[r]);
 r=w(y,0,0);P(" r=%d ", r);P("\n");
 F(m=0;m<6;++m)
        {P("N anno=%d -->",arr[m]);
         r=w(arr[m],0,0); // ritorna in r i mesi tramite i suoi bit...
         F(y=1;y<13;++y) I(r&(1<<y))P("%s ",mese[y-1]);
         P("\n");
        }
 F(m=0;m<4;++m)
        {P("N anno=%d -->",arr1[m]);
         r=z(arr1[m],0,0); // ritorna in r i mesi tramite i suoi bit...
         F(y=1;y<13;++y) I(r&(1<<y))P("%s ",mese[y-1]);
         P("\n");
        }

}

PowerShell Core, 73 65 bytes
param($a)1..12|?{"$_/1/$a"|get-date|% *hs 1|% *ys -1|? d*k -eq 1}

This requires the regional settings to use the en-US date format.
Explanations
Assumes the year is a string with padded zeros:
param($a)                     # Declares an input variable
1..12                         # Creates a range for each month
 |?                           # Filters each month
  {"$_/1/$a"                  # Creates a date for the first of the month Month/Day/Year
   |get-date
   |% *hs 1                   # *hs calls AddMonths
   |% *ys -1                  # *hs calls AddDays, -1 goes to the last day of the previous month
   |? d*k -eq 1}              # d*k calls DayOfWeek, 1 is the int value for the DayOfWeek.Monday

Thanks to mazzy for the idea of piping parameters into get-date!
Try it online!

[datetime]::new is really shorter! Nice! +a bit of CodeGolf

-3 bytes :)

thanks. the "$_/1/$a" works with the en_us region only. it does not work with german or russian regions.

Yes, I did it on purpose and had to adapt it to the Try it online culture.
Is it an ok approach? Or should use another solution?

I think it would be ok if you explicitly wrote about regional settings.

Japt, 13 bytes
Outputs an array of all months, where 0s are months that don't end in Mondays and all other integers are the 1-based indices of the months.
CõÈ*=1¶ÐUXJ e

Try it
If run in a locale where Monday is the first day of the week, with 0-based indexing, we could save 2 bytes with:
CõÈ*!ÐUXJ e

Or push the loose output format a little further by returning an array of Booleans with:
Cõ@!ÐUXJ e

Explanation
CõÈ*=1¶ÐUXJ e      :Implicit input of integer U
C                  :12
 õ                 :Range [1,C]
  È                :Map each X
   *=              :  Multiply by and reassign
     1¶            :  Test 1 for equality with
       Ð           :  Create date object using
        U          :    U for the year
         X         :    X for the 0-based month ([0,11]=[Jan,Dec] but [1,12]=[Feb,Jan])
          J        :    -1 for the date, wrapping us back to the last day of the previous month
            e      :  0-based index of the day of the week (0=Sunday)

CJam, 62 bytes
E,(;qiaf+{[~_2$3<_!-2*@@- 4/_25/_4/\W*](23*9/+:+7%4=}%ee::*0-`

Try it online!
Uses an algorithm adapted from Mike Keith. The program calculates the weekday of the first day of the next month, then checks if that day is a Tuesday. Output is a string representation of an array of month indices, e.g. [2 10].
If output can be in the form of a binary array with 0 meaning false and 1 meaning true for each of the 12 months, you can get away with 55 bytes.

T-SQL, 92 bytes
Input parameter needs to be padded with zeros if the year is before 1000
SELECT number+1FROM spt_values
WHERE number<12and
datepart(w,eomonth(@,number))=2and'P'=type

Try it online

Java (JDK), 141 136 bytes
y->{for(int i=0;++i<13)if(java.time.LocalDate.of(y,i,1).plusMonths(1).minusDays(1).getDayOfWeek().getValue()<2)System.out.println(i);};

Try it online!
To get the last day of each month I get the first day of the next month and substract 1 day. Java date function getDayOfWeek() returns the day of the week (Monday=1)
141 -> 136 : small improvements (thanks to @ceilingcat)

Groovy, 83 bytes
f={y->(1..12).findAll{sprintf('%ta',(java.time.YearMonth.of(y,it)+1<<1)-1)=='Mon'}}

Try it online!
The return format is a List of 1-based months.
(Doesn't currently work in TIO since it is using the YearMonth.plus(long months) method, which was added in Groovy 2.5.0.  TIO currently uses Groovy 2.4.8).
sprintf('%ta',value) returns the 3-letter month name.
YearMonth.of(y,it)+1 returns the YearMonth after the given month; YearMonth<<1 returns the LocalDate of the first of the month.  Subtracting 1 from this returns the last day of the previous month.  This is all just a convoluted way of returning YearMonth.of(y,it).atEndOfMonth() in 4 fewer characters.

Groovy, 57 bytes
f={y->(1..12).findAll{"${new Date(y+100,it,0)}"[0]=='M'}}

Try it online!
The return format is a List<Integer> of 0-based months.
This uses the legacy Date(int year, int month, int date) constructor that takes a year (minus 1900), the 0-based month, and the day of month.
The legacy Date class uses the Julian calendar prior to 1583.  However, the day-of-week is on a 400 year cycle, so I added 2000 (400*5) to the date.  Since 1900 has to be subtracted from the input date, I'm actually passing in the three-character number 100 (2000-1900) for the year.
In order to get the last day of the month, I'm passing in months 1-12 (February through the following year's January, since Date uses 0-based months) and day-of-month 0 (the day before the first of that month).  This gets me the last day of January - December of the given year.
Finally, the string representation of Date is in "Sun Nov 01 00:00:00 CDT 2020" format.  I'm converting the date to a GString using string interpolation, and then comparing the first character of that string to "M" for "Monday".

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Help me cheat at Cheat
Cheat is a card game where you're trying to get rid of your hand. A turn looks something roughly like this:

Determine what card rank you have to play that turn. In most variants this is one rank higher than the previous turn.
Play 1-4 cards, face down. These don't have to match the valid rank. If they don't, it's considered a cheat. At this point any player may challenge you.

If nobody challenges you, play continues to the next player.
If somebody challenges you and you didn't cheat, they have to take all of the played cards.
If somebody challenges you and you did cheat, you have to take all of the played cards.

The strategy is mostly a mix of bluffing and card counting. I'm bad at math, though, so I'm going to cheat at Cheat and bring a bot with me.
Input
The input will be, in any order or format you want:

The player's hand. If I know that they must have cards (for example, I've seen them pick them up), those will be listed in ascending order. Any unknowns will be listed afterwards as ?. For example, if they have six cards and I know that two are 1's and one is a 4, a valid representation of the hand is 114???. ?'s will always be listed after known cards. 141??? and 11???4 are both invalid inputs and your code doesn't need to handle them.
The cards I definitely know are not part of their hand (I have them, I saw someone else pick them up, etc). The list will be in ascending order of rank. The list may be empty.
The cards the player claimed to play. If they claimed to play 3 7's, a possible input here would be 777. The cards will always be the same rank.

The number of played cards will always be 1-4 and the ranks will always be 0-9. A rank will never appear more than four times in their hand + not their hand.
This is an example valid input:
33577??
01555688
55

This is an example invalid input:
35377?? # Out of order
7779    # Five 7's in total
23      # Two separate ranks played

Output
A truthy value if we should definitely challenge. A falsey value if we might not want to challenge.
We always challenge if we know they cheated. We know they cheated if they played cards they couldn't possibly have:
12

3  # They don't have any 3's or ?'s
-------------
12?

33 # Fewer ?'s than played cards
-------------
123?
333
33 # Since we have three 3's they can't have two

The other time we challenge is if they play their last cards. Even if the play's legit it would end the game so we might as well challenge it.
1

1 # They'd win, so challenge anyway

More Test Cases
Truthy (should challenge)
11445678?

22
-------------
????????
4
4444
-------------
12345678

9

Falsey (should not challenge)
1?
222
2
-------------
12?
22
22
-------------
?????

1111

Scoring
Shortest code wins.

This is bullsh*t :)

How many people are playing?

@jacksonecac you're only looking at one play, so you don't have to worry about how many players there are.

This should be a king-of-the-hill challange

The variant that I always played (BTW in Poland this game is called "chuj" which mean "dick" [or rather "dickhead" in that case]) there was rule that you are allowed to put 1, 2 or 4 cards, but not three. Also game was always for 4 players.

Shouldn't you be challenging in the second falsey case?

@StephenTG yup, I messed up. Fixing now

The test cases with cards you definitely know empty aren't really possible in a real game of Cheat, because you always know your own hand. ;)

Pyth, 22 bytes
!}zS+*hzhS,/Q\?-4l@z+w

Try it online.

JavaScript (ES6), 93 bytes
(h,s,c,g=(a,z=c[0])=>a.split(z).length-1)=>h.length==g(c)|g(h,'?')+g(h)<g(c)|g(h)+g(s)+g(c)>4

Accepts three strings of cards (characters 0-9 or ?); returns 1 for challenge, 0 otherwise. Explanation:
(h,s,c,                 Input parameters
 g=(a,z=c[0])=>         Helper function defaults to claimed card
  a.split(z).length-1   Count cards matching (g(c) == c.length)
)=>h.length==g(c)       Does hand length equal claim length
  |g(h,'?')+g(h)<g(c)   Could hand not contain claimed cards
  |g(h)+g(s)+g(c)>4     Are there too many claimed cards

C#6, 134 bytes
using System.Linq;
bool f(string a,string b,string c)=>a.Length==1|a.Count(x=>x==c[0]|x=='?')<c.Length|b.Count(x=>x==c[0])+c.Length>4;

(Note: In line with OP's example, this answer returns false even if opponent has more than one card and is playing all of his hand. In terms of strategy this should return true.)
Explanation:
a: Player's hand
b: Cards I definitely know...
c: Cards claimed to play
Ungolfed:
bool f(string a, string b, string c) =>
    a.Length == 1                               // Last card played
    | a.Count(x => x == c[0] | x == '?' )       // Count no. of cards that surely/may match claimed cards
                                                // Assuming all claimed cards are the same, just compare with c[0]
        < c.Length                              // I'm sure you don't have that many cards...
    | b.Count(x => x == c[0]) + c.Length > 4;   // ... Or that there can't be that many cards in play

Shouldn't a.Length==1 be a.Length==c.Length. You seem to imply something like that in your note, but I don't know which OP's example you are referring to that makes it possible that more cards are being played then the amount of cards the opponent has in their hand.

Java 8, 169 135 bytes
(a,b,c)->{int C=c.length();char x=c.charAt(0);return a.length()==C|(a+0).split(x+"|\\?",-1).length<=C|5-(b+0).split(""+x,-1).length<C;}

Explanation:
Try it here.
(a,b,c)->{            // Method with three String parameters and boolean return-type
  int C=c.length();   //  The amount of cards played by your opponent this turn
  char x=c.charAt(0); //  The card played by your opponent this turn
  return a.length()==C//  Return true if your opponent played his entire hand (final round)
    |(a+0).split(x+"|\\?",-1).length
                      //   Or the amount of the played card and '?' in your opponent's hand
      <=C             //   is smaller than the amount of cards played
    |5-(b+0).split(""+x,-1).length
                      //   Or if 4 minus the amount of the played card are part of the
                      //   cards you definitely know,
     <C;              //   is smaller than the amount of cards played
}                     // End of method

NOTE: (s+0).split("c",-1).length-1 gives the amount of times the character c occurs in String s. So the comments in the explanation above are correct, but the code might seem different because of it. The (a+0).split(x+"|\\?",-1).length-1<C is golfed to (a+0).split(x+"|\\?",-1).length<=C and the 4-(b+0).split(""+x,-1).length-1<C is golfed to 5-(b+0).split(""+x,-1).length<C.