long Ext2InitPartition(CICell ih) { long cnt, gdPerBlock; if (ih == gCurrentIH) return 0; printf("Ext2InitPartition: %x\n", ih); gCurrentIH = 0; // Read for the Super Block. Seek(ih, SBOFF); Read(ih, (long)gFSBuf, SBSIZE); gFS = (struct m_ext2fs *)gFSBuf; e2fs_sb_bswap(&gFS->e2fs, &gFS->e2fs); if (gFS->e2fs.e2fs_magic != E2FS_MAGIC) return -1; // Calculate the block size and set up the block cache. gBlockSize = 1024 << gFS->e2fs.e2fs_log_bsize; if (gBlockSizeOld <= gBlockSize) { gTempBlock = AllocateBootXMemory(gBlockSize); } CacheInit(ih, gBlockSize); gBlockSizeOld = gBlockSize; gCurrentIH = ih; gdPerBlock = gBlockSize / sizeof(struct ext2_gd); // Fill in the in memory super block fields. gFS->e2fs_bsize = 1024 << gFS->e2fs.e2fs_log_bsize; gFS->e2fs_bshift = LOG_MINBSIZE + gFS->e2fs.e2fs_log_bsize; gFS->e2fs_qbmask = gFS->e2fs_bsize - 1; gFS->e2fs_bmask = ~gFS->e2fs_qbmask; gFS->e2fs_fsbtodb = gFS->e2fs.e2fs_log_bsize + 1; gFS->e2fs_ncg = HowMany(gFS->e2fs.e2fs_bcount - gFS->e2fs.e2fs_first_dblock, gFS->e2fs.e2fs_bpg); gFS->e2fs_ngdb = HowMany(gFS->e2fs_ncg, gdPerBlock); gFS->e2fs_ipb = gFS->e2fs_bsize / EXT2_DINODE_SIZE; gFS->e2fs_itpg = gFS->e2fs.e2fs_ipg / gFS->e2fs_ipb; gFS->e2fs_gd = AllocateBootXMemory(gFS->e2fs_ngdb * gFS->e2fs_bsize); // Read the summary information from disk. for (cnt = 0; cnt < gFS->e2fs_ngdb; cnt++) { ReadBlock(((gBlockSize > 1024) ? 0 : 1) + cnt + 1, 0, gBlockSize, (char *)&gFS->e2fs_gd[gdPerBlock * cnt], 0); e2fs_cg_bswap(&gFS->e2fs_gd[gdPerBlock * cnt], &gFS->e2fs_gd[gdPerBlock * cnt], gBlockSize); } // Read the Root Inode ReadInode(EXT2_ROOTINO, &gRootInode, 0, 0); return 0; }
int main() { scanf("%d", &n); for (int i = 1; i <= n; i += 1) { scanf("%d", &marbles[i]); } Init(); int answer = n; int num_white = HowMany(1, n, white); int num_black = n - num_white; for (int i = 1; i + num_white - 1 <= n; i += 1) { int num_swaps = HowMany(i, num_white, black); answer = min(answer, num_swaps); } for (int i = 1; i + num_black - 1 <= n; i += 1) { int num_swaps = HowMany(i, num_black, white); answer = min(answer, num_swaps); } printf("%d\n", answer); return 0; }
WORD DoIfStatement(PHEAD WORD *ifcode, WORD *term) { GETBIDENTITY WORD *ifstop, *ifp; UWORD *coef1 = 0, *coef2, *coef3, *cc; WORD ncoef1, ncoef2, ncoef3, i = 0, first, *r, acoef, ismul1, ismul2, j; UWORD *Spac1, *Spac2; ifstop = ifcode + ifcode[1]; ifp = ifcode + 3; if ( ifp >= ifstop ) return(1); if ( ( ifp + ifp[1] ) >= ifstop ) { switch ( *ifp ) { case LONGNUMBER: if ( ifp[2] ) return(1); else return(0); case MATCH: case TYPEIF: if ( HowMany(BHEAD ifp,term) ) return(1); else return(0); case TYPEFINDLOOP: if ( Lus(term,ifp[3],ifp[4],ifp[5],ifp[6],ifp[2]) ) return(1); else return(0); case TYPECOUNT: if ( CountDo(term,ifp) ) return(1); else return(0); case COEFFI: case MULTIPLEOF: return(1); case IFDOLLAR: { DOLLARS d = Dollars + ifp[2]; #ifdef WITHPTHREADS int nummodopt, dtype = -1; if ( AS.MultiThreaded ) { for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) { if ( ifp[2] == ModOptdollars[nummodopt].number ) break; } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; if ( dtype == MODLOCAL ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } } } dtype = d->type; #else int dtype = d->type; /* We use dtype to make the operation atomic */ #endif if ( dtype == DOLZERO ) return(0); if ( dtype == DOLUNDEFINED ) { if ( AC.UnsureDollarMode == 0 ) { MesPrint("$%s is undefined",AC.dollarnames->namebuffer+d->name); Terminate(-1); } } } return(1); case IFEXPRESSION: r = ifp+2; j = ifp[1] - 2; while ( --j >= 0 ) { if ( *r == AR.CurExpr ) return(1); r++; } return(0); case IFISFACTORIZED: r = ifp+2; j = ifp[1] - 2; if ( j == 0 ) { if ( ( Expressions[AR.CurExpr].vflags & ISFACTORIZED ) != 0 ) return(1); else return(0); } while ( --j >= 0 ) { if ( ( Expressions[*r].vflags & ISFACTORIZED ) == 0 ) return(0); r++; } return(1); case IFOCCURS: { WORD *OccStop = ifp + ifp[1]; ifp += 2; while ( ifp < OccStop ) { if ( FindVar(ifp,term) == 1 ) return(1); if ( *ifp == DOTPRODUCT ) ifp += 3; else ifp += 2; } } return(0); default: /* Now we have a subexpression. Test first for one with a single item. */ if ( ifp[3] == ( ifp[1] + 3 ) ) return(DoIfStatement(BHEAD ifp,term)); ifstop = ifp + ifp[1]; ifp += 3; break; } } /* Here is the composite condition. */ coef3 = NumberMalloc("DoIfStatement"); Spac1 = NumberMalloc("DoIfStatement"); Spac2 = (UWORD *)(TermMalloc("DoIfStatement")); ncoef1 = 0; first = 1; ismul1 = 0; do { if ( !first ) { ifp += 2; if ( ifp[-2] == ORCOND && ncoef1 ) { coef1 = Spac1; ncoef1 = 1; coef1[0] = coef1[1] = 1; goto SkipCond; } if ( ifp[-2] == ANDCOND && !ncoef1 ) goto SkipCond; } coef2 = Spac2; ncoef2 = 1; ismul2 = 0; switch ( *ifp ) { case LONGNUMBER: ncoef2 = ifp[2]; j = 2*(ABS(ncoef2)); cc = (UWORD *)(ifp + 3); for ( i = 0; i < j; i++ ) coef2[i] = cc[i]; break; case MATCH: case TYPEIF: coef2[0] = HowMany(BHEAD ifp,term); coef2[1] = 1; if ( coef2[0] == 0 ) ncoef2 = 0; break; case TYPECOUNT: acoef = CountDo(term,ifp); coef2[0] = ABS(acoef); coef2[1] = 1; if ( acoef == 0 ) ncoef2 = 0; else if ( acoef < 0 ) ncoef2 = -1; break; case TYPEFINDLOOP: acoef = Lus(term,ifp[3],ifp[4],ifp[5],ifp[6],ifp[2]); coef2[0] = ABS(acoef); coef2[1] = 1; if ( acoef == 0 ) ncoef2 = 0; else if ( acoef < 0 ) ncoef2 = -1; break; case COEFFI: r = term + *term; ncoef2 = r[-1]; i = ABS(ncoef2); cc = (UWORD *)(r - i); if ( ncoef2 < 0 ) ncoef2 = (ncoef2+1)>>1; else ncoef2 = (ncoef2-1)>>1; i--; for ( j = 0; j < i; j++ ) coef2[j] = cc[j]; break; case SUBEXPR: ncoef2 = coef2[0] = DoIfStatement(BHEAD ifp,term); coef2[1] = 1; break; case MULTIPLEOF: ncoef2 = 1; coef2[0] = ifp[2]; coef2[1] = 1; ismul2 = 1; break; case IFDOLLAREXTRA: break; case IFDOLLAR: { /* We need to abstract a long rational in coef2 with length ncoef2. What if that cannot be done? */ DOLLARS d = Dollars + ifp[2]; #ifdef WITHPTHREADS int nummodopt, dtype = -1; if ( AS.MultiThreaded ) { for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) { if ( ifp[2] == ModOptdollars[nummodopt].number ) break; } if ( nummodopt < NumModOptdollars ) { dtype = ModOptdollars[nummodopt].type; if ( dtype == MODLOCAL ) { d = ModOptdollars[nummodopt].dstruct+AT.identity; } else { LOCK(d->pthreadslockread); } } } #endif /* We have to pick up the IFDOLLAREXTRA pieces for [1], [$y] etc. */ if ( ifp+3 < ifstop && ifp[3] == IFDOLLAREXTRA ) { if ( d->nfactors == 0 ) { MLOCK(ErrorMessageLock); MesPrint("Attempt to use a factor of an unfactored $-variable"); MUNLOCK(ErrorMessageLock); Terminate(-1); } { WORD num = GetIfDollarNum(ifp+3,ifstop); WORD *w; while ( ifp+3 < ifstop && ifp[3] == IFDOLLAREXTRA ) ifp += 3; if ( num > d->nfactors ) { MLOCK(ErrorMessageLock); MesPrint("Dollar factor number %s out of range",num); MUNLOCK(ErrorMessageLock); Terminate(-1); } if ( num == 0 ) { ncoef2 = 1; coef2[0] = d->nfactors; coef2[1] = 1; break; } w = d->factors[num-1].where; if ( w == 0 ) { if ( d->factors[num-1].value < 0 ) { ncoef2 = -1; coef2[0] = -d->factors[num-1].value; coef2[1] = 1; } else { ncoef2 = 1; coef2[0] = d->factors[num-1].value; coef2[1] = 1; } break; } if ( w[*w] == 0 ) { r = w + *w - 1; i = ABS(*r); if ( i == ( *w-1 ) ) { ncoef2 = (i-1)/2; if ( *r < 0 ) ncoef2 = -ncoef2; i--; cc = coef2; r = w + 1; while ( --i >= 0 ) *cc++ = (UWORD)(*r++); break; } } goto generic; } } else { switch ( d->type ) { case DOLUNDEFINED: if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is undefined",AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); Terminate(-1); } ncoef2 = 0; coef2[0] = 0; coef2[1] = 1; break; case DOLZERO: ncoef2 = coef2[0] = 0; coef2[1] = 1; break; case DOLSUBTERM: if ( d->where[0] != INDEX || d->where[1] != 3 || d->where[2] < 0 || d->where[2] >= AM.OffsetIndex ) { if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); Terminate(-1); } ncoef2 = 0; coef2[0] = 0; coef2[1] = 1; break; } d->index = d->where[2]; case DOLINDEX: if ( d->index == 0 ) { ncoef2 = coef2[0] = 0; coef2[1] = 1; } else if ( d->index > 0 && d->index < AM.OffsetIndex ) { ncoef2 = 1; coef2[0] = d->index; coef2[1] = 1; } else if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); Terminate(-1); } ncoef2 = coef2[0] = 0; coef2[1] = 1; break; case DOLWILDARGS: if ( d->where[0] <= -FUNCTION || ( d->where[0] < 0 && d->where[2] != 0 ) || ( d->where[0] > 0 && d->where[d->where[0]] != 0 ) ) { if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); Terminate(-1); } ncoef2 = coef2[0] = 0; coef2[1] = 1; break; } case DOLARGUMENT: if ( d->where[0] == -SNUMBER ) { if ( d->where[1] == 0 ) { ncoef2 = coef2[0] = 0; } else if ( d->where[1] < 0 ) { ncoef2 = -1; coef2[0] = -d->where[1]; } else { ncoef2 = 1; coef2[0] = d->where[1]; } coef2[1] = 1; } else if ( d->where[0] == -INDEX && d->where[1] >= 0 && d->where[1] < AM.OffsetIndex ) { if ( d->where[1] == 0 ) { ncoef2 = coef2[0] = 0; coef2[1] = 1; } else { ncoef2 = 1; coef2[0] = d->where[1]; coef2[1] = 1; } } else if ( d->where[0] > 0 && d->where[ARGHEAD] == (d->where[0]-ARGHEAD) && ABS(d->where[d->where[0]-1]) == (d->where[0] - ARGHEAD-1) ) { i = d->where[d->where[0]-1]; ncoef2 = (ABS(i)-1)/2; if ( i < 0 ) { ncoef2 = -ncoef2; i = -i; } i--; cc = coef2; r = d->where + ARGHEAD+1; while ( --i >= 0 ) *cc++ = (UWORD)(*r++); } else { if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); Terminate(-1); } ncoef2 = 0; coef2[0] = 0; coef2[1] = 1; } break; case DOLNUMBER: case DOLTERMS: if ( d->where[d->where[0]] == 0 ) { r = d->where + d->where[0]-1; i = ABS(*r); if ( i == ( d->where[0]-1 ) ) { ncoef2 = (i-1)/2; if ( *r < 0 ) ncoef2 = -ncoef2; i--; cc = coef2; r = d->where + 1; while ( --i >= 0 ) *cc++ = (UWORD)(*r++); break; } } generic:; if ( AC.UnsureDollarMode == 0 ) { #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif MLOCK(ErrorMessageLock); MesPrint("$%s is of wrong type",AC.dollarnames->namebuffer+d->name); MUNLOCK(ErrorMessageLock); Terminate(-1); } ncoef2 = 0; coef2[0] = 0; coef2[1] = 1; break; } } #ifdef WITHPTHREADS if ( dtype > 0 && dtype != MODLOCAL ) { UNLOCK(d->pthreadslockread); } #endif } break; case IFEXPRESSION: r = ifp+2; j = ifp[1] - 2; ncoef2 = 0; while ( --j >= 0 ) { if ( *r == AR.CurExpr ) { ncoef2 = 1; break; } r++; } coef2[0] = ncoef2; coef2[1] = 1; break; case IFISFACTORIZED: r = ifp+2; j = ifp[1] - 2; if ( j == 0 ) { ncoef2 = 0; if ( ( Expressions[AR.CurExpr].vflags & ISFACTORIZED ) != 0 ) { ncoef2 = 1; } } else { ncoef2 = 1; while ( --j >= 0 ) { if ( ( Expressions[*r].vflags & ISFACTORIZED ) == 0 ) { ncoef2 = 0; break; } r++; } } coef2[0] = ncoef2; coef2[1] = 1; break; case IFOCCURS: { WORD *OccStop = ifp + ifp[1], *ifpp = ifp+2; ncoef2 = 0; while ( ifpp < OccStop ) { if ( FindVar(ifpp,term) == 1 ) { ncoef2 = 1; break; } if ( *ifpp == DOTPRODUCT ) ifp += 3; else ifpp += 2; } coef2[0] = ncoef2; coef2[1] = 1; } break; default: break; } if ( !first ) { if ( ifp[-2] != ORCOND && ifp[-2] != ANDCOND ) { if ( ( ifp[-2] == EQUAL || ifp[-2] == NOTEQUAL ) && ( ismul2 || ismul1 ) ) { if ( ismul1 && ismul2 ) { if ( coef1[0] == coef2[0] ) i = 1; else i = 0; } else { if ( ismul1 ) { if ( ncoef2 ) Divvy(BHEAD coef2,&ncoef2,coef1,ncoef1); cc = coef2; ncoef3 = ncoef2; } else { if ( ncoef1 ) Divvy(BHEAD coef1,&ncoef1,coef2,ncoef2); cc = coef1; ncoef3 = ncoef1; } if ( ncoef3 < 0 ) ncoef3 = -ncoef3; if ( ncoef3 == 0 ) { if ( ifp[-2] == EQUAL ) i = 1; else i = 0; } else if ( cc[ncoef3] != 1 ) { if ( ifp[-2] == EQUAL ) i = 0; else i = 1; } else { for ( j = 1; j < ncoef3; j++ ) { if ( cc[ncoef3+j] != 0 ) break; } if ( j < ncoef3 ) { if ( ifp[-2] == EQUAL ) i = 0; else i = 1; } else if ( ifp[-2] == EQUAL ) i = 1; else i = 0; } } goto donemul; } else if ( AddRat(BHEAD coef1,ncoef1,coef2,-ncoef2,coef3,&ncoef3) ) { NumberFree(coef3,"DoIfStatement"); NumberFree(Spac1,"DoIfStatement"); TermFree(Spac2,"DoIfStatement"); MesCall("DoIfStatement"); return(-1); } switch ( ifp[-2] ) { case GREATER: if ( ncoef3 > 0 ) i = 1; else i = 0; break; case GREATEREQUAL: if ( ncoef3 >= 0 ) i = 1; else i = 0; break; case LESS: if ( ncoef3 < 0 ) i = 1; else i = 0; break; case LESSEQUAL: if ( ncoef3 <= 0 ) i = 1; else i = 0; break; case EQUAL: if ( ncoef3 == 0 ) i = 1; else i = 0; break; case NOTEQUAL: if ( ncoef3 != 0 ) i = 1; else i = 0; break; } donemul: if ( i ) { ncoef2 = 1; coef2 = Spac2; coef2[0] = coef2[1] = 1; } else ncoef2 = 0; ismul1 = ismul2 = 0; } } else { first = 0; } coef1 = Spac1; i = 2*ABS(ncoef2); for ( j = 0; j < i; j++ ) coef1[j] = coef2[j]; ncoef1 = ncoef2; SkipCond: ifp += ifp[1]; } while ( ifp < ifstop );