function submit(part)
  addpath('./lib');

  conf.assignmentKey = 'hdcdUQNgEealXw52htHS4Q';
  conf.itemName = 'CRF Learning for OCR';

  conf.partArrays = { ...
    { ...
      'QD9Fo', ...
      { '' }, ...
      '', ...
    }, ...
    { ...
      'apl5y', ...
      { '' }, ...
      '', ...
    }, ...
    { ...
      'n3klU', ...
      { '' }, ...
      '', ...
    }, ...
    { ...
      'I45dY', ...
      { '' }, ...
      '', ...
    }, ...
    { ...
      'jrVA2', ...
      { '' }, ...
      '', ...
    }, ...
    { ...
      'HIPL6', ...
      { '' }, ...
      '', ...
    }, ...
    { ...
      '0ctrF', ...
      { '' }, ...
      '', ...
    }, ...
    { ...
      'cM7Gc', ...
      { '' }, ...
      '', ...
    }, ...
    { ...
      'zl35t', ...
      { '' }, ...
      '', ...
    }, ...
    { ...
      'ZtLBP', ...
      { '' }, ...
      '', ...
    }, ...
  };

  conf.output = @output;
  submitWithConfiguration(conf);

end

% specifies which parts are test parts
function result = isTest(partIdx)
  if (mod(partIdx, 2) == 0)
      result = true;
  else
      result = false;
  end
end


function out = output(partId, auxstring)
if partId == 1
  load 'Train1X.mat';
  load 'Train1Y.mat';
  out = SerializeVector(LRTrainSGD(Train1X, Train1Y, 1));
elseif partId == 2
  load 'Train2X.mat';
  load 'Train2Y.mat';
  out = SerializeVector(LRTrainSGD(Train2X, Train2Y, 1));  
elseif partId == 3
  load 'Train1X.mat';
  load 'Train1Y.mat';
  load 'Validation1X.mat';
  load 'Validation1Y.mat';  
  Test3Lambdas = [2 8];  
  out = SerializeVector(LRSearchLambdaSGD(Train1X, Train1Y, Validation1X, Validation1Y, Test3Lambdas));
elseif partId == 4
  load 'Train2X.mat';
  load 'Train2Y.mat';
  load 'Validation2X.mat';
  load 'Validation2Y.mat';  
  Test4Lambdas = [2 8];    
  out = SerializeVector(LRSearchLambdaSGD(Train2X, Train2Y, Validation2X, Validation2Y, Test4Lambdas));
elseif partId == 5
    load Part2Sample.mat;
    [dummy, logZ] = CliqueTreeCalibrate(sampleUncalibratedTree, false);
    out = num2str(logZ);
elseif partId == 6
    load Part2LogZTest.mat;
    [dummy, logZ] = CliqueTreeCalibrate(logZTestCliqueTree, false);
    out = num2str(logZ);
elseif partId == 7
    load Part2Sample.mat;
    [nll, grad] = InstanceNegLogLikelihood(sampleX, sampleY, sampleTheta, sampleModelParams);
    out = num2str(nll);
elseif partId == 8
    load Part2Test.mat;
    [nll, grad] = InstanceNegLogLikelihood(testX, testY, testTheta, testModelParams);
    out = num2str(nll);
elseif partId == 9
    load Part2Sample.mat;
    [nll, grad] = InstanceNegLogLikelihood(sampleX, sampleY, sampleTheta, sampleModelParams);
    out = SerializeVector(grad);
elseif partId == 10
    load Part2Test.mat;
    [nll, grad] = InstanceNegLogLikelihood(testX, testY, testTheta, testModelParams);
    out = SerializeVector(grad);
end

end

function out = SerializeVector(x)
  % Serializes a numeric (floating point) vector. 
  numLines = length(x);
  lines = cell(numLines,1);
  for i=1:numLines
    lines{i} = sprintf('%.4f\n', x(i));
  end
  out = sprintf('%s', lines{:});
end

function out = SerializeIntVector(x)
  % Serializes an integer vector. 
  numLines = length(x);
  lines = cell(numLines,1);
  for i=1:numLines
    lines{i} = sprintf('%d\n', x(i));
  end
  out = sprintf('%s', lines{:});
end
