using System;
using System.Collections.Generic;
using System.Linq;
public class YukicoScore6
{
public static void Main(string[] args)
{
#if DEBUG
// 入力ファイルを流し込んで使うときにフォーマット差を吸収する
Console.ReadLine();
#endif
var solver = new Solver();
for (int turn = 0; turn < 1000; turn++)
{
var n = int.Parse(Console.ReadLine());
if (n == -1) return;
for (int j = 0; j < n; j++)
{
var nums = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
var enemy = new Enemy(nums[0], nums[1], turn);
solver.AddEnemy( nums[2], enemy);
}
var cmd = solver.GetCommand();
Console.WriteLine(cmd);
Console.Out.Flush();
solver.ExecCommand(cmd);
}
}
}
public class Solver
{
Random Random = new Random(1728);
State State = new State();
public string GetCommand()
{
var bestScore = int.MinValue;
var bestX = State.PlayerX;
var bestCmd = "S";
for (int x = 0; x < Inputs.Width; x++)
{
var canShootTurn = State.Turn;
for (int i = 0; i < State.Columns[x].Count; i++)
{
var enemy = State.Columns[x][i];
var attackTurn = (int)Math.Ceiling(enemy.HP / (double)(State.PlayerLevel));
// todo 衝突を回避する前提でターンを考える
var moveTurn1 = Math.Abs(x - State.PlayerX); // ループしない
var moveTurn2 = Math.Abs(0 - State.PlayerX) + Math.Abs(Inputs.Width - x); // 左側へループ
var moveTurn3 = Math.Abs(Inputs.Width - State.PlayerX) + Math.Abs(0 - x); // 右側へループ
var bestMoveTurn = Math.Min(Math.Min(moveTurn1, moveTurn2), moveTurn3);
if (canShootTurn + attackTurn + bestMoveTurn - 1 >= GetEnemyCollisionTurn(enemy)) // 倒すのが間に合わない(衝突)
{
canShootTurn = GetEnemyCollisionTurn(enemy) + 1;
continue;
}
if (State.Turn + attackTurn + bestMoveTurn >= 1000) continue; // 倒すのが間に合わない(時間切れ)
var score = (State.PlayerLevel < 180 ? enemy.Power : enemy.InitHP) * 10000 / (attackTurn + bestMoveTurn);
if (State.Turn >= 100) score = score * (100 + (State.Turn - enemy.AppearanceTurn));
if (State.PlayerLevel < 5) score += ((State.PlayerPower + enemy.Power) / 100) * 100;
if (score > bestScore)
{
bestScore = score;
bestX = x;
if (moveTurn1 <= moveTurn2 && moveTurn1 <= moveTurn3)
{
bestCmd = x == State.PlayerX ? "S" : (x < State.PlayerX ? "L" : "R");
}
else if (moveTurn2 <= moveTurn1 && moveTurn2 <= moveTurn3)
{
bestCmd = "L";
}
else
{
bestCmd = "R";
}
}
break;
}
}
// 無理矢理に衝突を回避する
// 敵→自機で動くので、自分が動いた後と次ターンの敵が動くときに衝突の可能性がある
if (bestCmd == "L")
{
var nextX = (State.PlayerX + Inputs.Width - 1) % Inputs.Width;
var enemy = State.GetFirstEnemy(nextX);
var colTurn = enemy == null ? -1 : GetEnemyCollisionTurn(enemy);
if (enemy != null && (colTurn == State.Turn || colTurn == State.Turn + 1)) bestCmd = "S";
}
if (bestCmd == "R")
{
var nextX = (State.PlayerX + 1) % Inputs.Width;
var enemy = State.GetFirstEnemy(nextX);
var colTurn = enemy == null ? -1 : GetEnemyCollisionTurn(enemy);
if (enemy != null && (colTurn == State.Turn || colTurn == State.Turn + 1)) bestCmd = "S";
}
if (bestCmd == "S")
{
var nextX = State.PlayerX;
var enemy = State.GetFirstEnemy(nextX);
var colTurn = enemy == null ? -1 : GetEnemyCollisionTurn(enemy);
if (enemy != null && (colTurn == State.Turn || colTurn == State.Turn + 1))
{
// todo 2体連続している場合はバグる。時間と気力が効果に見合えば直す
var leftX = (State.PlayerX + Inputs.Width - 1) % Inputs.Width;
var leftEnemy = State.GetFirstEnemy(leftX);
var colTurnL = leftEnemy == null ? -1 : GetEnemyCollisionTurn(leftEnemy);
if (leftEnemy == null || (colTurnL != State.Turn && colTurnL != State.Turn + 1)) bestCmd = "L";
var rightX = (State.PlayerX + 1) % Inputs.Width;
var rightEnemy = State.GetFirstEnemy(rightX);
var colTurnR = rightEnemy == null ? -1 : GetEnemyCollisionTurn(rightEnemy);
if (rightEnemy == null || (colTurnR != State.Turn && colTurnR != State.Turn + 1)) bestCmd = "R";
}
}
return bestCmd;
}
public void ExecCommand(string cmd)
{
State.Turn++;
State.RemoveOldEnemy();
if (cmd == "L") State.PlayerX = (State.PlayerX + Inputs.Width - 1) % Inputs.Width;
if (cmd == "R") State.PlayerX = (State.PlayerX + 1) % Inputs.Width;
var enemy = State.GetFirstEnemy(State.PlayerX);
if (enemy == null) return;
enemy.HP -= State.PlayerLevel;
if (enemy.HP > 0) return;
State.RemoveFirstEnemy(State.PlayerX);
State.PlayerPower += enemy.Power;
State.PlayerLevel = 1 + State.PlayerPower / 100;
}
public void AddEnemy(int x, Enemy enemy)
{
State.AddEnemy(x, enemy);
}
/// 敵と自機が衝突するターンを取得する
private int GetEnemyCollisionTurn(Enemy enemy)
{
return enemy.AppearanceTurn + Inputs.Height - 1;
}
}
public class State
{
public int Turn { get; set; }
/// 列ごとの敵リスト
public List[] Columns = new List[Inputs.Width];
public int PlayerX { get; set; } = 12;
public int PlayerPower { get; set; } = 0;
public int PlayerLevel { get; set; } = 1;
public State()
{
for (int i = 0; i < Inputs.Width; i++)
{
Columns[i] = new List();
}
}
public void AddEnemy(int x, Enemy enemy)
{
Columns[x].Add(enemy);
}
public Enemy? GetFirstEnemy(int x)
{
if (!Columns[x].Any()) return null;
return Columns[x][0];
}
public void RemoveOldEnemy()
{
for (int x = 0; x < Inputs.Width; x++)
{
if (!Columns[x].Any()) continue;
var bottomEnemy = Columns[x][0];
if (bottomEnemy.AppearanceTurn + Inputs.Height <= Turn)
{
Columns[x].RemoveAt(0);
}
}
}
public void RemoveFirstEnemy(int x)
{
Columns[x].RemoveAt(0);
}
}
public class Inputs
{
public const int Width = 25;
public const int Height = 60;
}
public class Enemy
{
public int InitHP { get; }
public int HP { get; set; }
public int Power { get; }
/// 出現ターン
public int AppearanceTurn { get; }
public Enemy(int initHP, int power, int appearanceTurn)
{
InitHP = initHP;
HP = initHP;
Power = power;
AppearanceTurn = appearanceTurn;
}
}