Files
Aislo/B08_Quantity/B08_Quantity_Haul_Cycle.ts
T
eomsangdonandClaude Opus 5.5 01bca00e3c feat(b08): 운반 사이클시간 짝 · 로직 입력 거리 채움 (253-2)
- B08_Quantity_Haul_Cycle.py · .ts 짝 — 건설품셈 8-2-8 덤프트럭 · 거창 25 단가산출 1308~1347행 재현(t1 5.33 · t2 101.23 · Cm 109.78)
- 로직 입력 이름 채움 Cm · 사이클시간 · t2 · 운반거리 · 덮은 칸(own) 그대로
- B09 셈(hand_sources) 때 거리이정표 거리로 다시 채움 · 덮개 ref 에 cycle · own 남김

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JywHxQuWPk6UYXTebyrBoU
2026-10-11 14:03:54 +09:00

94 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* =============================================================================
* B08_Quantity_Haul_Cycle.ts
* B08 운반 사이클시간(PLAN 253-2) — 건설품셈 8-2-8 덤프트럭 · 거리이정표 거리 → 운반 로직 입력.
*
* ⚠ 짝 = `B08_Quantity_Haul_Cycle.py`(같은 식) — 한쪽을 고치면 다른 쪽도 ·
* 거울 시험 `resources/tester/test_253_2_haul_cycle.py`.
* 조작 중은 이 파일(「운반 단가」 모달)이 바로 셈 · B09 셈 때 서버가 짝으로 다시 채움(정본).
*
* 식 = q = T / rt × f · n = q / (qs × k) · t1 = Cms × n / (60 × Es) ·
* t2 = (L1/V1 + L1/V2 + L2/V3 + L2/V4) × 60 · Cm = t1 + … + t6 · 끝수 = 소수 둘째 자리 ·
* 속도 0 = 그 항 0 · 로직 입력 채움 = Cm · 사이클시간 = Cm · t2 · 운반거리 = L1 + L2 ·
* `own` = 사용자가 덮은 칸(그 값이 이김).
* ========================================================================== */
export const CYCLE_DEFAULTS: Record<string, number> = {
L1: 0,
L2: 0,
V1: 30,
V2: 35,
V3: 10,
V4: 15,
T: 15,
rt: 1.7,
f: 1,
qs: 1.72,
k: 1,
Es: 0.6,
Cms: 37.4,
t3: 0.8,
t4: 0.42,
t5: 0.5,
t6: 1.5,
};
/** 로직 입력 이름 → 셈 결과 칸 */
export const CYCLE_FILL: Record<string, "cm" | "t2" | "L"> = {
Cm: "cm",
사이클시간: "cm",
t2: "t2",
운반거리: "L",
};
export interface CycleResult {
q: number;
n: number;
t1: number;
t2: number;
cm: number;
L: number;
}
export interface CycleRef {
given?: Record<string, unknown> | null;
cycle?: Record<string, unknown> | null;
own?: string[] | null;
}
export type Dist = { L1?: number | null; L2?: number | null } | null | undefined;
/** 소수 둘째 자리 반올림(0.5 올림 · 파이썬 짝 `r2`) */
export const r2 = (value: number): number => Math.floor(value * 100 + 0.5) / 100;
const div = (a: number, b: number): number => (b ? a / b : 0);
const num = (value: unknown): number | null =>
typeof value === "number" && Number.isFinite(value) ? value : null;
/** 사이클 입력(빈 칸 = 기본값 · t1 있으면 그 값) → {q, n, t1, t2, cm, L} */
export function cycleTime(inputs: Record<string, unknown> | null | undefined): CycleResult {
const v: Record<string, number> = {};
for (const [k, d] of Object.entries(CYCLE_DEFAULTS)) v[k] = num(inputs?.[k]) ?? d;
const q = r2(div(v.T, v.rt) * v.f);
const n = r2(div(q, v.qs * v.k));
const t1 = num(inputs?.t1) ?? r2(div(v.Cms * n, 60 * v.Es));
const t2 = r2((div(v.L1, v.V1) + div(v.L1, v.V2) + div(v.L2, v.V3) + div(v.L2, v.V4)) * 60);
const cm = r2(t1 + t2 + v.t3 + v.t4 + v.t5 + v.t6);
return { q, n, t1, t2, cm, L: Math.floor((v.L1 + v.L2) * 1000 + 0.5) / 1000 };
}
/** 연결 `ref.cycle` + 거리이정표 거리 — 덮은 L1 · L2(`ref.own`)는 그대로 */
export function cycleInputs(ref: CycleRef | null | undefined, dist: Dist): Record<string, unknown> {
const cycle: Record<string, unknown> = { ...(ref?.cycle || {}) };
const own = new Set(ref?.own || []);
for (const name of ["L1", "L2"] as const)
if (!own.has(name) && num(dist?.[name]) !== null) cycle[name] = dist?.[name];
if (!own.has("t1")) delete cycle.t1;
return cycle;
}
/** 로직 입력값 다시 채움 — names = 그 로직 입력 이름 · 덮은 칸은 그대로 */
export function fillGiven(ref: CycleRef, names: string[], dist: Dist): Record<string, unknown> {
const own = new Set(ref.own || []);
const got = cycleTime(cycleInputs(ref, dist));
const given: Record<string, unknown> = { ...(ref.given || {}) };
for (const [name, slot] of Object.entries(CYCLE_FILL))
if (names.includes(name) && !own.has(name)) given[name] = got[slot];
return given;
}