Пример #1
0
int main( void )
{
    int  i     = 0;
    int  Pay   = 0 ;
    int  Price = 0;
    int  UnitCount = 0;
    int* CoinUnits = NULL;
    int* Change    = NULL;
    
    printf("동전의 가짓수를 입력하세요 :"); 
    scanf( "%d", &UnitCount );

    CoinUnits = (int*) malloc( sizeof(int) * UnitCount );
    Change    = (int*) malloc( sizeof(int) * UnitCount );

    for ( i=0; i<UnitCount; i++ )
    {
        printf("[%d] 번째 동전의 단위를 입력하세요 : ", i );
        scanf( "%d", &CoinUnits[i] );
    }

    qsort( CoinUnits, UnitCount, sizeof(int), Compare );

    printf("물건 가격을 입력하세요 : ");
    scanf( "%d", &Price );

    printf("손님이 지불한 돈은 얼마입니까? : ");
    scanf( "%d", &Pay );

    GetChange( Price, Pay, CoinUnits, Change, UnitCount );
    
    PrintChange( CoinUnits, Change, UnitCount);

    return 0;
}
Пример #2
0
static STATUS_T CmdPrint(
		wAction_t action,
		coOrd pos )
/*
 * Print command:
 *
 * 3 Sub-states:
 *		Select - grid coordinates are computed and the selected page is marked.
 *		Move - grid base (currPrintGrid.orig) is moved.
 *		Rotate - grid base and angle is rotated about selected point.
 */
{
	STATUS_T rc = C_CONTINUE;
	static BOOL_T downShift;

	switch (action) {

	case C_START:
		if (!wPrintInit())
			return C_TERMINATE;
		printScale = iPrintScale;
		if (printWin == NULL) {
			rminScale_999.low = 1;
			if (printScale < rminScale_999.low)
				printScale = rminScale_999.low;
			print_d.scale = printScale;
			printWin = ParamCreateDialog( &printPG, MakeWindowTitle(_("Print")), _("Print"), DoPrintPrint, (paramActionCancelProc)Reset, TRUE, NULL, 0, PrintDlgUpdate );
		}
		wShow( printWin );
		SetPageSize( TRUE );
		if (currPrintGrid.size.x == 0.0) {
			currPrintGrid.size.x = maxPageSize.x;
			currPrintGrid.size.y = maxPageSize.y;
		}
		if (currPrintGrid.size.x >= maxPageSize.x)
			currPrintGrid.size.x = maxPageSize.x;
		if (currPrintGrid.size.y >= maxPageSize.y)
			currPrintGrid.size.y = maxPageSize.y;
		newPrintGrid = currPrintGrid;
		ParamLoadControls( &printPG );
		DrawPrintGrid();
		pageCount = 0;
LOG( log_print, 2, ( "Page size = %0.3f %0.3f\n", currPrintGrid.size.x, currPrintGrid.size.y ) )
		PrintChange( CHANGE_MAP|CHANGE_UNITS );
		ParamGroupRecord( &printPG );
		ParamLoadMessage( &printPG, I_PAGECNT, "0 pages" );
		ParamDialogOkActive( &printPG, FALSE );
		ChangeDim();
		InfoMessage( _("Select pages to print, or drag to move print grid") );
		downShift = FALSE;
		ParamControlActive( &printPG, I_RULER, currPrintGrid.angle == 0 );
		return C_CONTINUE;

	case C_DOWN:
		downShift = FALSE;
		if (MyGetKeyState()&WKEY_SHIFT) {
			newPrintGrid = currPrintGrid;
			rc = GridAction( C_DOWN, pos, &newPrintGrid.orig, &newPrintGrid.angle );
			downShift = TRUE;
		}
		return C_CONTINUE;

	case C_MOVE:
		if (downShift) {
			rc = GridAction( action, pos, &newPrintGrid.orig, &newPrintGrid.angle );
			ParamLoadControls( &printPG );
		}
		return C_CONTINUE;

	case C_UP:
		if (downShift) {
			rc = GridAction( action, pos, &newPrintGrid.orig, &newPrintGrid.angle );
			ParamLoadControls( &printPG );
			DrawPrintGrid();
			currPrintGrid = newPrintGrid;
			ChangeDim();
			DrawPrintGrid();
			downShift = FALSE;
		}
		return C_CONTINUE;

	case C_LCLICK:
		SelectPage( pos );
		return C_CONTINUE;

	case C_RDOWN:
		downShift = FALSE;
		if (MyGetKeyState()&WKEY_SHIFT) {
			newPrintGrid = currPrintGrid;
			rc = GridAction( action, pos, &newPrintGrid.orig, &newPrintGrid.angle );
			downShift = TRUE;
		}
		return rc;

	case C_RMOVE:
		if (downShift) {
			rc = GridAction( action, pos, &newPrintGrid.orig, &newPrintGrid.angle );
			ParamLoadControls( &printPG );
		}
		return rc;

	case C_RUP:
		if (downShift) {
			rc = GridAction( action, pos, &newPrintGrid.orig, &newPrintGrid.angle );
			ParamLoadControls( &printPG );
			DrawPrintGrid();
			currPrintGrid = newPrintGrid;
			ChangeDim();
			DrawPrintGrid();
			downShift = FALSE;
			ParamControlActive( &printPG, I_RULER, currPrintGrid.angle == 0 );
		}
		return rc;

	case C_REDRAW:
		DrawPrintGrid();
		return C_TERMINATE;

	case C_CANCEL:
		if (printWin == NULL)
			return C_TERMINATE;
		PrintClear();
		DrawPrintGrid();
		wHide( printWin );
		return C_TERMINATE;

	case C_OK:
		DoPrintPrint( NULL );
		return C_TERMINATE;

	case C_CMDMENU:
		wMenuPopupShow( printGridPopupM );
		return C_CONTINUE;

	default:
		return C_CONTINUE;
	}
}
Пример #3
0
Bool OptimizeLoop(Var * proc, InstrBlock * header, InstrBlock * end)
/*
1. Find loop (starting with inner loops)
   - Every jump to label preceding the jump (backjump) forms a label
   - In nested labels, we encounter the backjump first
				<code1>
			l1@
				<code2>
			l2@
				<code3>
				if.. l2@
				<code4>
				if.. l3@
				<code5>

2. Select variable to put to register
   - Most used variable should be used
   - Some variables are already moved to index register (this is considered use too)

3. Compute cost of moving the variable to register

*/
{
	Instr * i, initial, ti, * last_mod;
	Var * top_var, * reg, * top_reg, * orig_result;
	UInt16 r, regi, changed;
	UInt32 var_size;
	Int32 q, top_q, n;
	Bool init, top_init;
	InstrBlock * blk, * last_mod_blk;
	InstrBlock * blk_exit;
	Bool var_modified;
	Bool verbose;
	Rule * rule;
	UInt8 color;

	blk_exit = end->next;

	G_VERBOSE = verbose = Verbose(proc);
	VarResetUse();
	InstrVarUse(header, blk_exit);
	InstrVarLoopDependent(header, end);

	// When processing, we assign var to register
	for(regi = 0; regi < CPU->REG_CNT; regi++) CPU->REG[regi]->var = NULL;

	while(top_var = FindMostUsedVar()) {

//		if (Verbose(proc)) {
//			Print("Most user var: "); PrintVar(top_var); PrintEOL();
//		}

		top_var->read = top_var->write = 0;
		var_size = VarByteSize(top_var);

		//====== Select the best register for the given variable
		//      let %A,%A   => index -3
		//      use of register instead of variable -1
		//      spill +3

		top_q = 0; top_reg = NULL; top_init = false;

		for(regi = 0; regi < CPU->REG_CNT; regi++) {

			reg = CPU->REG[regi];
			if (FlagOn(reg->submode, SUBMODE_IN|SUBMODE_OUT)) continue;		// exclude input/output registers
			if (reg->type->range.max == 1) continue;						// exclude flag registers
			if (var_size != VarByteSize(reg)) continue;						// exclude registers with different byte size
			if (reg->var != NULL) continue;

			if (InstrRule2(INSTR_LET, reg, top_var, NULL)) {

	//			if (StrEqual(reg->name, "x") && StrEqual(top_var->name, "i")) {
	//				Print(" ");
	//			}
				q = UsageQuotient(header, end, top_var, reg, &init);

				if (q < top_q) {
					top_q = q;
					top_reg = reg;
					top_init = init;
				}
			}
		}

		if (top_reg == NULL) continue;

		reg = top_reg;
		if (Verbose(proc)) {
			color = PrintColor(OPTIMIZE_COLOR);
			PrintFmt("*** Loop %d..%d\n", header->seq_no, end->seq_no);
			Print("Var: "); PrintVarVal(top_var); PrintEOL();
			Print("Register: "); PrintVarName(top_reg); PrintEOL();
			PrintFmt("Quotient: %d\n", top_q);
			PrintColor(color);
		}

		//TODO: If there is Let reg = var and var is not top_var, we need to spill store

		//=== Replace the use of registers

//		PrintProc(proc);

		ResetValues();
		initial.op = INSTR_LET; initial.result = top_reg; initial.arg1 = top_var; initial.arg2 = NULL;

		var_modified = false;
		// Generate instruction initializing the register used to replace the variable
		// before the start of the loop.
		// We only do this, if the variable is not initialized inside the loop.

//		if (FlagOn(top_var->flags, VarUninitialized) && !top_init) {
//			top_init = true;
//		}

 		if (top_init) {
			LoopInsertPrologue(proc, header, INSTR_LET, top_reg, top_var, NULL);
			VarSetSrcInstr(top_reg, &initial);
		}
		r = 0;

		last_mod = NULL;

		for(blk = header; blk != blk_exit; blk = blk->next) {
			if (verbose) PrintBlockHeader(blk);
			for(i = blk->first, n=0; i != NULL; i = i->next) {
retry:
				n++;
				if (i->op == INSTR_LINE) {
					if (verbose) { PrintInstrLine(n); EmitInstrInline(i); PrintEOL(); }
					continue;
				}

				// Delete unnecessary assignment
				if (i->op == INSTR_LET) {
					if (!InVar(i->arg1) && !OutVar(i->result) && VarContains(i->result, i->arg1)) {
del:
						if (verbose) { PrintInstrLine(n); EmitInstrInline(i); }
del2:					if (verbose) { PrintDelete(); }
						i = InstrDelete(blk, i);
						if (i == NULL) break;
						goto retry;	//continue;
					}
				}

				// Load the register with variable if necessary
				if (InstrReadsVar(i, top_var)) {
					if (!VarContains(top_reg, top_var)) {
						if (!(i->op == INSTR_LET && i->result == top_reg && i->arg1 == top_var)) {
							InstrInsertRule(blk, i, INSTR_LET, top_reg, top_var, NULL);
						}
					}
				}

				if (i->op == INSTR_LET && (i->result == top_var && i->arg1 == top_reg)) {
					r++;
					goto del;
				}

				if (InstrSpill(i, top_var)) {
					InstrInsertRule(blk, i, INSTR_LET, top_var, top_reg, NULL);
				}

				if (verbose) { PrintInstrLine(n); EmitInstrInline(i); }

				orig_result = i->result;

				memcpy(&ti, i, sizeof(Instr));
				changed = VarTestReplace(&ti.result, top_var, reg);
				r += changed;
				changed += VarTestReplace(&ti.arg1, top_var, reg);
				changed += VarTestReplace(&ti.arg2, top_var, reg);

				// If the instruction used variable, that contains same value as replaced register, use the register instead
				if (ti.arg1 != reg && VarContains(ti.arg1, reg)) {
					changed += VarTestReplace(&ti.result, ti.arg1, reg);
					changed += VarTestReplace(&ti.arg2, ti.arg1, reg);
					changed += VarTestReplace(&ti.arg1, ti.arg1, reg);
				}

				if (changed > 0) {

					if (i->op == INSTR_LET && ti.result == ti.arg1) {
						goto del2;
					}

					rule = InstrRule(&ti);
					if (rule != NULL && (i->rule->cycles >= rule->cycles)) {
						InstrReplaceVar(i, top_var, top_reg);

						if (i->arg1 != reg && VarContains(i->arg1, reg)) {
							VarTestReplace(&i->result, i->arg1, reg);
							VarTestReplace(&i->arg2, i->arg1, reg);
							VarTestReplace(&i->arg1, i->arg1, reg);
						}

						i->rule = rule;
						CheckInstr(i);
						PrintChange(i);
					}

				}

				if (verbose) PrintEOL();
				ResetValue(i->result);
				if (orig_result == top_var) {
//					if (!InstrIsSelfReferencing(i)) {
						VarSetSrcInstr(i->result, &initial);
//					} else {
//						VarSetSrcInstr(i->result, NULL);
//					}
					last_mod = i; last_mod_blk = blk;
				} else {
					VarSetSrcInstr(i->result, i);
				}
			}
		}

		// Value of register is not known at the end of loop, but it is not initialized at the beginning of the loop
		// We must load it before first use.

		if (!top_init && last_mod) {
			InstrInsertRule(last_mod_blk, last_mod->next, INSTR_LET, top_var, top_reg, NULL);
		}

		// If we replaced some destination by the register, store the register to destination
		if (r > 0) {
			// There may be exit label as part of the loop
			// We need to spill after it

			if (!VarIsConst(top_var)) {
				if (blk_exit == NULL || blk_exit->callers != NULL || blk_exit->from != end) {
					blk_exit = InstrBlockAlloc();
					blk_exit->to = end->to;
					blk_exit->next = end->to;
					end->next = blk_exit;
					end->to   = blk_exit;
				}
				InstrInsertRule(blk_exit, blk_exit->first, INSTR_LET, top_var, top_reg, NULL);
			}
//			InstrInsert(blk_exit, blk_exit->first, INSTR_LET, top_var, top_reg, NULL);
		}

		if (FlagOn(top_var->flags, VarLoopDependent)) {
			reg->flags |= VarLoopDependent;
		}

		return true;
	}
	return false;
}